一、Problem
Koko loves to eat bananas. There are N piles of bananas, the i-th pile has piles[i] bananas. The guards have gone and will come back in H hours.
Koko can decide her bananas-per-hour eating speed of K. Each hour, she chooses some pile of bananas, and eats K bananas from that pile. If the pile has less than K bananas, she eats all of them instead, and won’t eat any more bananas during this hour.
Koko likes to eat slowly, but still wants to finish eating all the bananas before the guards come back.
Return the minimum integer K such that she can eat all the bananas within H hours.
Input: piles = [3,6,7,11], H = 8
Output: 4
二、Solution
方法一:二分
目標是求喫完所有香蕉的最小速度,而數值大的速度 s 能在 H 小時內喫完,那麼 > s 的速度也一定能,所以只需要縮小查找速度的邊界即可。
class Solution {
int H, ps[];
boolean ck(int s) {
int h = 0;
for (int p : ps) {
h += p / s;
if (p % s != 0) h++;
if (h > H)
return false;
}
return true;
}
public int minEatingSpeed(int[] piles, int H) {
int l = 1, r = 0;
this.H = H; this.ps = piles;
for (int p : ps) if (p > r) {
r = p;
}
while (l < r) {
int s = l + r >>> 1;
if (ck(s)) r = s;
else l = s+ 1;
}
return r;
}
}
向上取整的寫法還有比較高效的寫法:
h += (p+s-1) / s
證明: 等於 向上取整的結果正確性
- 如果 ,有 ,
- 如果 ,又有 ,
class Solution {
int H, ps[];
boolean ck(int s) {
int h = 0;
for (int p : ps) {
h += (p+s-1)/s;
if (h > H)
return false;
}
return true;
}
public int minEatingSpeed(int[] piles, int H) {
int l = 1, r = 0;
this.H = H; this.ps = piles;
for (int p : ps) if (p > r)
r = p;
while (l < r) {
int mid = l + r >>> 1;
if (ck(mid)) r = mid;
else l = mid + 1;
}
return r;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,