二分答案是binary search里面比较难的题型,也就是,直接求一个最值很难,但是我们可以很简单的在解空间做判定性问题,比如能不能,行不行,大了还是小了,return true or false,从而缩小解空间,记住,这种方法有个前提条件就是有单调递增或者递减的性质,才能用。这也是binary search使用的条件;
一般来说,最后判断start, end 的时候,判断条件跟之前判断mid的条件是一样的,题目要求最大还是最小,首先判断返回end,或者start。
以后记住,minimax的题目,基本上都是binary search + greedy helper function。
思路:直接求,比较难求,但是我们可以二分解空间;
K 800 400 ..... 8 7 6
L 1 2 ...... x-1 x x+1
也就是如果L持续增大,那么能够切出来的整块在减少,那么就有个递增和递减的关系,L越大,K越小;反之亦然;
那么就可以用二分法;把一个求解最值的问题,变成一个判定性问题;
public class Solution {
/**
* @param L: Given n pieces of wood with length L[i]
* @param k: An integer
* @return: The maximum length of the small pieces
*/
public int woodCut(int[] L, int k) {
if(L == null || L.length == 0) {
return 0;
}
int start = 0;
int end = 0;
for(int l: L) {
end = Math.max(end, l);
}
while(start + 1 < end) {
int mid = start + (end - start) / 2;
if(cancut(L, mid) >= k) {
start = mid;
} else {
end = mid;
}
}
if(cancut(L, end) >= k) {
return end;
}
return start;
}
private int cancut(int[] L, int len) {
int count = 0;
for(int l : L) {
count += l / len;
}
return count;
}
}
Copy Books 思路:二分答案,直接求不好求,那么我们就问,如果给你无穷多的人,你需要多久? Max(Length of page[i]), 如果给你1个人,你需要多久,sum (Pages[i]) ,那么问题来了,你需要求给你k个人情况下的,你需要多久。很显然,这又是个递增递减的关系;人越多,需要的时间越少,人越少需要的时间越多;
public class Solution {
/**
* @param pages: an array of integers
* @param k: An integer
* @return: an integer
*/
public int copyBooks(int[] pages, int k) {
if(pages == null || pages.length == 0) {
return 0;
}
int start = 0; // max(p)
int end = 0; // sum(p)
for(int p: pages) {
start = Math.max(start, p);
end += p;
}
while(start + 1 < end) {
int mid = start + (end - start) / 2;
if(needPerson(mid, pages) > k) {
start = mid;
} else {
// needPerson(mid, pages) <= k
end = mid;
}
}
if(needPerson(start, pages) > k) { // 这个判断条件,跟上面的判断start, end一模一样;
return end;
}
return start;
}
private int needPerson(int timelimit, int[] pages) {
int count = 0;
int sum = 0;
int i = 0;
while(i < pages.length) {
// 为了计算在时间limit下,一个人能够抄多少,最后计算出需要多少人在限定时间下能够抄完;
while(i < pages.length && sum + pages[i] <= timelimit) {
sum += pages[i];
i++;
}
count++;
sum = 0;
}
return