410. Split Array Largest Sum

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:

If n is the length of array, assume the following constraints are satisfied:

1 ≤ n ≤ 1000

1 ≤ m ≤ min(50, n)

Examples:

Input: nums = [7,2,5,10,8] m = 2

Output: 18

Explanation:

There are four ways to split nums into two subarrays.

The best way is to split it into [7,2,5] and [10,8],

where the largest sum among the two subarrays is only 18.

S: Binary Search + greedy O(nlogn)

left = 数组中最大的元素, right = 数组所有元素之和,不管怎么划分,non-empty continuous subarray sum一定在[let, right]区间。对此区间进行二分查找:

若可以用m-1次cut将数组分为m份,每份的sum都小于或等于mid,则所求target一定小于等于mid,否则所求target一定大于mid。left,right为target的boundary,最终结果一定在left和right中

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        int left = 0, right = 0;
        for (int i : nums) {  //find left, right boundary
            left = max(i, left);
            right += i;
        }
        while (left + 1 < right) {
            int mid = left + (right - left) / 2;
            if (doable(nums, m - 1, mid)) {
                right = mid;
            } else {
                left = mid;
            }
        }
        if (doable(nums, m - 1, left)) {
            return left;
        } else {
            return right;
        }
    } 

private:
    bool doable(vector<int>& nums, int cuts, int maxSum) {  //greedy aproach
        int curSum = 0;
        for (int i : nums) {
            if (curSum + i <= maxSum) {
                curSum += i;
            } else {  //add one cut, new segment start at i
                cuts--;
                curSum = i;
                if (cuts < 0) {
                    return false;
                }
            }
        }
        return true;
    }
};

results matching ""

    No results matching ""