1. 程式人生 > >Leetcode 410. Split Array Largest Sum 劃分陣列 解題報告

Leetcode 410. Split Array Largest Sum 劃分陣列 解題報告

1 解題思想

首先宣告下,本文這些內容,基本是dicuss的來的

題目意思是,給一個數組,需要劃分成m份,讓你找出一種劃分方式,使得劃分成m份後,最大的那一個區間的數值最小

這道題discuss上說的是2分查詢,我也確實想不到更好的方式:
1、首先這個區間的值肯定是在[最大的單個數,所有陣列只和] 中間的
2、利用二分查詢的思想進行查詢,查詢範圍和1的標註那個一樣,必須要那個
3、查詢時用valid驗證,對於當前這個值,能否合法的劃分出來?是多了還是少了,所謂的不合法就是說對於給定值,必須要劃分了多餘m個區間,才能讓給定值是所有劃分區間裡最大值小於等於給定值

2 原題

Given an
array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000. Examples: Input: nums = [1
,2,3,4,5] m = 2 Output: 9 Explanation: There are four ways to split nums into two subarrays. The best way is to split it into [1,2,3] and [4,5], where the largest sum among the two subarrays is only 9.

3 AC解

來自discuss
public class Solution {
    /**
     *  這個數肯定介於最大的那一個單值和所有元素只和的中間
     * */
    public
int splitArray(int[] nums, int m) { long sum = 0; int max = 0; for(int num: nums){ max = Math.max(max, num); sum += num; } return (int)binarySearch(nums, m, sum, max); } //二分查詢 private long binarySearch(int[] nums, int m, long high, long low){ long mid = 0; while(low < high){ mid = (high + low)/2; //驗證是否滿足,也就是這麼大的值有可能出現麼 if(valid(nums, m, mid)){ high = mid; }else{ low = mid + 1; } } return high; } /** * 驗證這個值是否合法 * */ private boolean valid(int[] nums, int m, long max){ int cur = 0; int count = 1; //是否有多餘m個片段or區間,大於給定值的max的,如果有了,那麼就不合法了,因為這樣劃分就不止m個,及max太小 for(int num: nums){ cur += num; if(cur > max){ cur = num; count++; if(count > m){ return false; } } } return true; } }