410. Split Array Largest Sum

Posted yaoyudadudu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.

 

解题思路:

刚看到这道题没有一点思路,于是参考了HaoxiangXu的解法

它的解法讲得非常清晰透彻了。

这里用到了二分法和贪婪算法来一起做。

 

首先将问题分成了两个子问题:

1.  给出一个数组arr,给定分割数m以及每个组的最大和MAX,能否用最多m个分割将数组分成子数组和不超过MAX的子数组?

2. 给出一个下界left,和一个上界right,一个未知的bool数组(B)以及一个使用i作为输入并且告诉你B[i]是否为true的API。若我们知道,一定存在一个下标k,使得i<k 时,B[i] 为false, i >= k时, B[i]为true。 找到k的最快的方式是什么?

 

对于第一个问题, 我们可以使用贪婪算法来解答。在组中加入当前数字n,判断当前的组合是否超出MAX,若超出,则将当前数字作为新的组的起点,更新新的组和为当前数字n,并且分割数减一(因为开始了新的组,我们需要用一个分割来分割两个组)。

注意此时要判断分割数是否小于0,若分割数小于0,则代表当前分割数无法分割出组和不超过MAX的子数组们。

 

对于第二个问题,我们很容易想到二分搜索。

 

回归到当前问题,我们需要寻找上界(right)和下界(left)。

最小的分割为只有一个元素,最大的分割为原数组,所以left = max(arr), right = sum(arr);

 

给大神跪了ORZ

 

代码:

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        long long left = 0, right = 0;
        for(int n : nums){
            left = max(left, (long long)n);
            right += (long long)n;
        }
        while(left < right){
            long long mid = left + (right - left)/2;
            if(isWork(nums, m-1, mid)) right = mid;
            else left = mid+1;
        }
        return left;
    }
private:
    bool isWork(vector<int>& nums, int cuts, long long max){
        int acc = 0;
        for(int n : nums){
            if(n > max) return false;
            if(acc + n <= max) acc += n;
            else{
                acc = n;
                cuts--;
                if(cuts < 0) return false;
            }
        }
        return true;
    }
};

 


以上是关于410. Split Array Largest Sum的主要内容,如果未能解决你的问题,请参考以下文章

410. Split Array Largest Sum

410. Split Array Largest Sum

410. Split Array Largest Sum

Split Array Largest Sum LT410

Leetcode 410. Split Array Largest Sum

leetcode 410. Split Array Largest Sum