algorithm final 1
Binary Search
Split Array Largest Sum 410
二分求最大最小
Given an array nums 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.
Example 1:
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.
暴力解法
[7, 12, 2, 5, 6, 8, 3] m = 3
/ / \
7 7,12 7, 12, 2, 5, 6, 8, 3
2 分 最大最小就会用到
[7, 12, 2, 5, 6, 8, 3] m = 3
lo = max(nums) 12, 当 m 很多很多的时候,达到了 n - 1 个
hi = 43 当 m 就一个的时候数值
2 分分的是 m 的值
DO binary search while lo < hi
- iteration
- mid
- is splittable into m subarrays at sum <= mid
lo = 12, hi = 43
1st —> mid 27 —> [7, 12, 2, 5,|| 6, 8, 3]
iterate 的时候,在 sum >= mid 值就停下,这样就有 小于等于 mid 的数值, 这里是 26 和 16,切了 2 刀 小于 3,所以取大了
lo = 12, hi = 27
2st —> mid 18 —> [7, || 12, 2,|| 5, 6, ||8, 3]
这里切了 4 刀, 大于 3, 取小了
lo = 19, hi = 27
3st —> mid 23 —> [7, 12, 2,|| 5, 6, 8, 3]
这里切了 2 刀, 小于 3,所以取大了
lo = 19, hi = 23
4st —> mid 21 —> [7, 12, 2,|| 5, 6, 8, || 3]
这里切了 3 刀, 等于 3, 可能取大了
lo = 19, hi = 21
5st —> mid 20 —> [7, 12, || 2, 5, 6, || 8, 3]
这里切了 3 刀, 等于 3, 可能取大了
lo = 19, hi = 20
6st —> mid 19 —> [7, 12, || 2, 5, 6, || 8, 3]
这里切了 3 刀, 等于 3, 可能取大了
lo = hi = 19, return hi 19
public int splitArray(int[] nums, int m) {
// 1 5 9
int sum = Arrays.stream(nums).sum();
int max = Arrays.stream(nums).max().getAsInt();
return binary(nums, m, sum, max);
}
// 10, 24
//
private int binary(int[] nums, int m, int high, int low) {
int mid = 0;
while (low <= high) {
mid = low + (high - low) / 2;
if (valid(nums, m, mid)) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
private boolean valid(int[] nums, int m, int subArraySum) {
int curSum = 0, count = 1;
for (int num : nums) {
curSum += num;
if (curSum > subArraySum) {
curSum = num;
count++;
if (count > m) {
return false;
}
}
}
return true;
}