LC410. Split Array Largest Sum

Posted betaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LC410. Split Array Largest Sum相关的知识,希望对你有一定的参考价值。

技术图片

把一个数组分成m个连续子数组(不能有空数组),求所有分法中,子数组sum的最大值的最小值。

方法1:容易想到的是动态规划

dp[i][j] = min(max(dp[k-1][j-1], sum[k][i]) 1 <= k <= i, dp[i][j]表示用前i个数字,分成j组,最大和的最小值

time:$O(nnm)$ space:$O(nm)$

class Solution {
public:
    typedef long long ll;
    ll INF = 1e15;
    int splitArray(vector<int>& nums, int m) {
        int n = nums.size();
        vector<vector<ll>> dp(n + 1, vector<ll>(m + 1, INF));
        dp[0][0] = 0;
        vector<ll> sums(n + 1, 0);
        for (int i = 0; i < n; ++i) sums[i + 1] = sums[i] + nums[i];
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                for (int k = 1; k <= i; ++k) {
                    dp[i][j] = min(dp[i][j], max(dp[k - 1][j - 1], sums[i] - sums[k - 1]));
                }
            }
        }
        return dp[n][m];
    }
};

方法2:贪心+二分

 check(LL sum, vector<int>& nu) 函数判断数组能否被分成m段,最大的和不超过sum,用了贪心的思路,cnt表示最少能分多少段,使最大和不超过sum,因此,分当前段的时候,取尽可能多的数,如果最后cnt <= m,说明我肯定能分出m段,如果cnt < m,只要拆开一些段就行,最大和并不会变坏。假如某个数大于sum,则无论怎么分,都无法分出m(m > 1)段。
然后用二分去找最小的sum,能使check返回true,相当于找lower_bound

 

class Solution {
public:
    typedef long long LL;
    int m;
    bool check(LL sum, vector<int>& nu) {
        LL nsum = 0;
        int cnt = 1;
        for (int i : nu) {
            if (i > sum) return false;
            if (i + nsum > sum) {
                cnt++;
                nsum = i;
            }
            else 
                nsum += i;
        }
        return cnt <= m;
    }
    int splitArray(vector<int>& nums, int m) {
        int n = nums.size();
        this->m = m;
        LL l = 0, r = 0;
        for (int i : nums) r += i;
        LL mid, ans = r;
        while (l <= r) {
            mid = (l + r) >> 1;
            if (check(mid, nums)) {
                ans = min(ans, mid);
                r = mid - 1;
            }
            else l = mid + 1;
        }
        return ans;
    }
};

 

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

410. Split Array Largest Sum

Leetcode410. 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