410 Split Array Largest Sum
update 2018-10-12 13:40:38
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.
Basic Idea:
这道题目的DP解法确实不容易想到,但这种解法本身是不难理解的。这个问题本质是求:将给定长度为n的数组分成m段subarray,使得所有subarray中sum的最大值最小
,于是我们可以定义子问题:将长度为n-k的数组分成m-1段,使所有subarray中sum的最大值最小
。然后我们发现可以由子问题推出下一层的解,这就符合了DP求解一个问题的规律。
发现youtube上有一个花花酱的视频,个人感觉讲得不错,看这个截图就可以理解了:

这个做法的时间复杂度为 O(m*n^2)
;
Java Code:
class Solution { public int splitArray(int[] nums, int m) { int[] prefixSum = new int[nums.length + 1]; for (int i = 0; i < nums.length; ++i) { prefixSum[i + 1] = prefixSum[i] + nums[i]; } int[][] dp = new int[m + 1][nums.length + 1]; for (int i = 1; i < nums.length + 1; ++i) { dp[1][i] = prefixSum[i]; } for (int i = 2; i <= m; ++i) { for (int j = 1; j <= nums.length; ++j) { int minSum = Integer.MAX_VALUE; for (int k = 1; k < j; ++k) { minSum = Math.min(minSum, Math.max(dp[i - 1][k], prefixSum[j] - prefixSum[k])); } dp[i][j] = minSum; } } return dp[m][nums.length]; } }
update Oct 26, 2019
Java Binary Search Solution
基本思路是一个基于结果的二分法。
class Solution {
public int splitArray(int[] nums, int m) {
int sum = 0, max = 0;
for (int n : nums) {
sum += n;
max = Math.max(max, n);
}
int left = max, right = sum;
while (left + 1 < right) {
int mid = left + (right - left) / 2;
if (canSplit(nums, m, mid)) {
right = mid;
} else {
left = mid;
}
}
if (canSplit(nums, m, left)) return left;
else return right;
}
private boolean canSplit(int[] nums, int m, int maxSum) {
int sum = 0;
for (int i = 0; i < nums.length; ++i) {
sum += nums[i];
if (sum > maxSum) {
sum = nums[i];
m--;
}
if (m == 0) return false;
}
return true;
}
}
Last updated