public static int splitArray(int[] nums, int k) {
int sum=0;
int max=0;
for (int num : nums) {
if(num>max){
max=num;
}
sum+=num;
}
int l=max-1;
int r=sum+1;
while((l+1)!=r){
int m=(l+r)/2;
if(split(nums,m)>k){
l=m;
}else{
r=m;
}
}
return r;
}
public static int split(int[] nums,int max){
int splits=1;
int sum=0;
for (int num : nums) {
if(sum+num>max){
splits++;
sum=0;
}
sum+=num;
}
return splits;
}
如何利用单调性:
随着子数组各自和(sum)的最大值 变大的过程中, 分割数会越来越小
所以我们在sum中进行二分查找,找到刚刚好使得分割数splits减小时的sum
在对sum的二分查找中,左侧代表着分割数大于k的,右侧分割数是大于等于k的
所以当循环结束时,r指向的是 刚刚好使得分割数=k的 子数组各自和最大值的最小值