410. Split Array Largest Sum

Posted ruruozhenhao

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.

 

Approach #1:  Plan Recursion (Up to Bottom)

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        const int n = nums.size();
        sums_ = vector<int>(n);
        mem_ = vector<vector<int>>(n, vector<int>(m + 1, INT_MAX));
        sums_[0] = nums[0];
        for (int i = 1; i < n; ++i) {
            sums_[i] = nums[i] + sums_[i-1];        // prefix sum
        }
        return helper(nums, n-1, m);
    }
private:
    int helper(const vector<int>& nums, int k, int m) {
        if (m == 1) return sums_[k];        // split one group. 
        if (m > k + 1) return INT_MAX;      // split groups more than the elements.
        if (mem_[k][m] != INT_MAX) return mem_[k][m];       // return the have memeried status
        int ans = INT_MAX;
        for (int i = 0; i < k; ++i) 
            ans = min(ans, max(helper(nums, i, m-1), sums_[k] - sums_[i]));     // calculation minimize largest sum. 
        return mem_[k][m] = ans;
    }
    vector<vector<int>> mem_;
    vector<int> sums_;
};

Runtime: 116 ms, faster than 2.38% of C++ online submissions for Split Array Largest Sum.

 

Approach #2: DP (Bottom to Up)

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        const int n = nums.size();  // if I don‘t use const it will not compile successfully.
        vector<int> sum(n+1);
        vector<vector<int>> dp(m+1, vector<int>(n, INT_MAX));
        sum[0] = nums[0];
        for (int i = 1; i < n; ++i) 
            sum[i] = sum[i-1] + nums[i];
        for (int i = 0; i < n; ++i) 
            dp[1][i] = sum[i];      // the status with only one group;
        for (int i = 2; i <= m; ++i) {
            for (int j = i-1; j < n; ++j) {
                for (int k = 0; k < j; ++k) {
                    dp[i][j] = min(dp[i][j], max(dp[i-1][k], sum[j] - sum[k]));
                }
            }
        }
        return dp[m][n-1];
    }
};
Runtime: 116 ms, faster than 2.38% of C++ online submissions for Split Array Largest Sum.

 

Approach #3: Binary Search:

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        int l = 0, r = 0;
        for (auto& num : nums) {    // if don‘t use auto& it won‘t compile successfully.
            l = max(l, num);
            r += num;        // the answer must exsit bewteen in the l and r.
        }
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (canSplit(nums, m, mid))
                r = mid - 1;
            else 
                l = mid + 1;
        }
        return l;
    }
private:
    bool canSplit(vector<int>& nums, int m, int mid) {
        int c = 1;
        int sum = 0;
        for (auto& num : nums) {
            sum += num;
            if (sum > mid) {
                c++;
                sum = num;
            }
        }
        return c <= m;
    }
};

Runtime: 4 ms, faster than 49.91% of C++ online submissions for Split Array Largest Sum.

 

以上是关于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