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.
结果一定是在数组中最大的数和所有数字之和 的中间
注意: sum 用 long 来表示
之后使用二分法,用valid 函数 来检查是否成立
valid函数 从左到右 依次添加, total 表示 临时的和
如果total 大于 target, 把 total 设为 此刻的num,并 cnt++。如果cnt 大于 m,返回 false。(我们选的数小了,分的段数大于m,得把左边 mid +1)
反之, r = mid - 1
public int splitArray(int[] nums, int m) {
int max = 0;
long sum = 0;
for (int num : nums) {
max = Math.max(max, num);
sum += num;
}
if (m == 1) return (int)sum;
long l = max;
long r = sum;
while (l <= r) {
long mid = (l + r) / 2;
if (valid(mid, nums, m)) r = mid - 1;
else l = mid + 1;
}
return (int)l;
}
private boolean valid(long target, int[] nums, int m) {
int cnt = 1;
long total = 0;
for (int num : nums) {
total += num;
if (total > target) {
total = num;
cnt++;
if (cnt > m) return false;
}
}
return true;
}