给定一个非负整数数组 nums 和一个整数 m ,你需要将这个数组分成 m 个非空的连续子数组。
设计一个算法使得这 m 个子数组各自和的最大值最小。
/*
*二分法:
*例:nums = [7,2,5,10,8]
*若 m=1, 最小的最大值为32;
*若 m=5, 最小的最大值为10;
*1<=m<=5, 则最大的最小值取值范围:[10,32]
*所以利用二分法找出符合m的最大值的最小结果
*left=10;
*right=32;
*mid = (left+right)/2; //21
*假设最开始分的子数组个数为count 1
*将数组元素逐个放进去
*7<21
*7+2<21
*7+2+5<21
*7+2+5+10>21
*
*所以 1个21容量的子数组无法容纳整个数组元素
*则 count++
*10<21
*10+8<21
*
*此时count==m,两个子数组能够将整个数组元素放入
*
*所以最后分的结果为: [7,2,5]和[10,8]
*
*如果最后count>m,说明容量mid偏小,要扩大,left=mid+1
*如果最后count<m,说明容量mid偏大,要缩小,right=mid
*
*
*/
class Solution {
public int splitArray(int[] nums, int m) {
long l=0;
long r=0;
for(int i=0;i<nums.length;i++){
l = Math.max(l,nums[i]);
r += nums[i];
}
long mid=0;
while(l<r){
mid = (r-l)/2+l;
if(check(mid,nums,m)){
r = mid;
}else{
l = mid+1;
}
}
return (int)l;
}
public boolean check(long limit,int[] nums,int m){
long total=0;
long counts=1;
for(int i=0;i<nums.length;i++){
total += nums[i];
if(total>limit){
counts++;
total = nums[i];
}
}
return counts<=m;
}
}