【二分】piles[i]<=10^9,因此二分解空间最多log(10^9)=30次,每次检查piles.length长度的数组,判断当前所用次数和h的关系,如果check出来的次数<=h,说明我们取的值太大了,要继续往左查找,否则往右查找。这样最后查完之后左边都是完成不了的,返回右区间的左端点也就是left即可。
class Solution {
int[] p;
int h;
int check(int x){
int ret = 0;
double a = (double)x;
for(var i: p){
ret += (int)Math.ceil(i / a);
}
return ret;
}
int binarySearch(int left, int right){
while(left <= right){
int mid = (left + right) >>> 1;
if(check(mid) <= h){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
}
public int minEatingSpeed(int[] piles, int h) {
p = piles;
this.h = h;
int max = p[0];
for(var i: p) max = Math.max(i, max);
return binarySearch(1, max);
}
}
【优化】其实check的时候如果发现已经>h了可以直接返回一个>h的数,后面的完全就不用管了。
另外向上取整可以这么写(i + x - 1) / x
class Solution {
int[] p;
int h;
public int check(int x){
int ret = 0;
for(var i: p) {
ret += (i + x - 1) / x;
if(ret > h) return ret;
}
return ret;
}
public int minEatingSpeed(int[] piles, int h) {
p = piles;
int right = p[0];
this.h = h;
for(var i: p) right = Math.max(i, right);
int left = 1;
while(left <= right){
int mid = (left + right) >>> 1;
if(check(mid) <= h) right = mid - 1;
else left = mid + 1;
}
return left;
}
}