1251 · Split Array Largest Sum
Algorithms
Hard
Description
Given an array which consists of non-negative integers and an integer m, we are going to split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.
If n is the length of array, assume the following constraints are satisfied:
1 ≤ n ≤ 1000
1 ≤ m ≤ min(50, n)
https://kns.cnki.net/kns8/defaultresult/index
Example
Example 1:
Input:[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.
Example 2:
Input:[1,4,4], m = 3
Output:4
Explanation:
There is a way to split nums into three subarrays.
The best way is to split it into [1], [4] and [4],
where the largest sum among the three subarrays is only 4.
解法1:binary search。
二分思想在下面的链接中解释得比较清楚。
https://www.cnblogs.com/grandyang/p/5933787.html
一些需要注意的地方:
- can_split(nums, m, thresh) 表示nums[]数组能否分成m个连续子数组,使得其中最大连续子数组的和不超过thresh。如果nums[]数组已经能分成<m个连续子数组且其中最大连续子数组的和不超过thresh,那么nums[]数组肯定也能分成m个连续子数组且其中最大连续子数组的和不超过thresh。这就是为什么can_split() 函数里面最后当num_subarrs <= m时就直接返回true了。
- 如果can_split(nums, m, thresh)成立,那么比thresh更大的thresh’肯定也成立,我们需要找到更小的thresh,所以取end=mid。
最后我们先判断start,再判断end,因为我们要取小的那个。
class Solution {
public:
/**
* @param nums: a list of integers
* @param m: an integer
* @return: return a integer
*/
int splitArray(vector<int> &nums, int m) {
int n = nums.size();
if (n == 0) return 0;
int max_elem = *max_element(nums.begin(), nums.end());
int sum = 0;
for (int i = 0; i < n; ++i) sum += nums[i];
int start = max_elem, end = sum;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (can_split(nums, m, mid)) {
end = mid;
} else {
start = mid;
}
}
if (can_split(nums, m, start)) return start;
if (can_split(nums, m, end)) return end;
}
private:
bool can_split(vector<int> &nums, int m, int thresh) {
int n = nums.size();
int index = 0, sum = 0;
int num_subarrs = 1;
while (index < n) {
sum += nums[index];
if (sum > thresh) {
sum = nums[index];
num_subarrs++;
if (num_subarrs > m) return false;
}
index++;
}
// if (num_subarrs == m) return true; //错误
// return false; //错误
return true;
}
};
解法2:DP。TBD。
本文介绍了解决 Split Array Largest Sum 问题的方法,包括使用二分查找和动态规划两种算法思路。通过实例演示如何将数组分割成指定数量的连续子数组,使其中的最大和最小化。
1028

被折叠的 条评论
为什么被折叠?



