有一些原木,现在想把这些木头切割成一些长度相同的小段木头,需要得到的小段的数目至少为 k。当然,我们希望得到的小段越长越好,你需要计算能够得到的小段木头的最大长度。
注意事项
木头长度的单位是厘米。原木的长度都是正整数,我们要求切割得到的小段木头的长度也要求是整数。无法切出要求至少 k 段的,则返回 0 即可。
样例
有3根木头[232, 124, 456], k=7,最大长度为114.
挑战
O(n logLen), Len为 n 段原木中最大的长度
===================================================================================
从题目可知道,可以切割的木头长度的范围,为 [1 ~ 最大原木长度],答案就在这个区间中。
在一个递增的区间中求答案很容易就想到二分法。
public int woodCut(int[] L, int k) {
int max = Integer.MIN_VALUE;
for(int i : L) max = Math.max(max, i); //获取最大原木长度
int left = 1;
int right = max;
int count = 0;
while(left+1<right){
int mid = left + (right - left)/2; //等价于 (left + right)/2 , 防止溢出。
count = 0;
for(int i : L)count+=i/mid;
if(count>=k){
left = mid;
}else{
right = mid;
}
}
count = 0;
for(int i : L)count+=i/right;
if(count>=k){
return right;
}
count = 0;
for(int i : L)count+=i/left;
if(count>=k){
return left;
}
return 0;
}
}
public int woodCut(int[] L, int k) {
int max = Integer.MIN_VALUE,count = 0;
for(int i : L) max = Math.max(max, i);
while(max>0){
for(int i : L)count+=i/max;
if(count>=k)return max;
count = 0;
max--;
}
return 0;
}