Problem
Given n pieces of wood with length L[i] (integer array). Cut them into small pieces to guarantee you could have equal or more than k pieces with the same length. What is the longest length you can get from the n pieces of wood? Given L & k, return the maximum length of the small pieces.
Notice
You couldn't cut wood into float length.
Example
For L=[232, 124, 456]
, k=7
, return 114
.
Challenge
O(n log Len), where Len is the longest length of the wood.
Note
有长度为L[]的一堆木头,要切出k段相同长度的木头,找到最大可能切出的长度。
考虑两种极端的长度,单位1
,以及sort后最长那根木头的长度,L[n-1]
。我们要找的答案一定在这两种长度之间,所以可以用二分法。
在1
和L[n-1]
作为start
和end
的情况下,我们需要计算每个对应的mid
,以及这个mid
所对应的能切成的等长木段数sum
。若sum
大于要求的k
,那么还可以增大mid
的长度,也就是令start
前移到mid
,继续计算。若sum
小于要求的k
,就必须减小mid
。最后start
和end
相交时的mid
,就是所求的最大长度。
不过在这个二分法的使用中,我们在最后跳出while循环之后很难分别判断start和end哪个能够满足条件。因为必须重新用start,end甚至start + 1,end - 1计算sum,才能得到最优的结果。所以,我们要令start和end最终相交于一点,同时直接得到所求最优解,直到下一次循环`start > end`时,结束循环。
**这种循环的写法是:**
**1.**
`while (start <= end)`
**2.**
if (mid satisfies or about to satisfy the requirement) {
res = mid;
start = mid++;
}
**3.**
else end = mid--;
Solution
public class Solution {
public int woodCut(int[] L, int k) {
int n = L.length;
if (n == 0) return 0;
Arrays.sort(L);
int start = 1;
int end = L[n-1];
int res = 0;
while (start <= end) {
int mid = start + (end - start)/2;
int sum = 0;
for (int i = 0; i < n; i++) {
sum+=L[i]/mid;
}
if (sum >= k) {
res = mid;
start = mid + 1;
}
else end = mid - 1;
}
return res;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。