-
Notifications
You must be signed in to change notification settings - Fork 643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
腾讯&leetcode875:爱吃香蕉的珂珂 #109
Comments
解答:二分查找二分查找也称折半查找算法,它是一种简单易懂的快速查找算法。例如我随机写0-100之间的一个数字,让你猜我写的是什么?你每猜一次,我就会告诉你猜的大了还是小了,直到猜中为止。 该算法要求待查找的数组已排序,实现步骤如下:
对应于本题,二分查找查找的是珂珂吃香蕉的速度
const minEatingSpeed = (piles, H) => {
// 计算堆中香蕉最大值
let maxVal = 1;
for (let pile of piles) {
maxVal = Math.max(maxVal, pile);
}
// 速度最小的时候,耗时最长
let low = 1
// 速度最大的时候,耗时最短
let high = maxVal
while (low < high) {
let mid = Math.floor((low+high)/2)
if (calculateTime(piles, mid) > H) {
// 耗时太多,说明速度太慢了,进入下一轮搜索
low = mid + 1
} else {
high = mid
}
}
return low
}
// 计算吃掉香蕉所需的总耗时
const calculateTime = (piles, speed) => {
let times = 0
for (let pile of piles) {
// 向上取整
times += Math.ceil(pile / speed)
}
return times
} 复杂度分析:
|
const piles = [3,6,7,11];
const H = 8;
const getSpeed = (piles, H) => {
if (H === piles.length) {
return Math.max(...piles);
} else if (H < piles.length) {
return false;
} else {
const max = Math.max(...piles);
const min = Math.min(...piles);
const ratio = H / piles.length;
const minSpeed = Math.ceil(min / ratio);
const maxSpeed = Math.ceil(max / ratio);
for (speed = minSpeed; speed <= maxSpeed; speed++) {
let totalTime = 0;
for (let i = 0; i < piles.length; i++) {
totalTime += Math.ceil(piles[i] / speed);
}
if (totalTime === H) {
return speed;
}
}
}
};
const a = getSpeed(piles, H);
console.log(a); |
/*
题解1(易于理解,但不是最优解)
以[3,6,7,11] 堆为例,
1.假设1小时吃1根,则总时间是 3/1 + 6/1 + 7/1 + 11/1 = 27
2.假设1小时吃2根,则总时间是 3/2 + 6/2 + 7/2 + 11/2 => 2(向上取整) + 3 + 4 + 6 = 15
3.假设1小时吃3根,则总时间是 3/3 + 6/3 + 7/3 + 11/3 => 1 + 2 + 3 + 4 = 10
4.假设1小时吃4根,则总时间是 3/4 + 6/4 + 7/4 + 11/4 => 1 + 2 + 2 + 3 = 8 (满足)
...后面速度越快,时间越短
*/
var minEatingSpeed = function(piles, H) {
let index = 1;
while(true){
let resH = 0;
for(let i = 0; i < piles.length; i++){
resH += Math.ceil(piles[i] / index);
}
if(resH <= H){
return index;
}
index++;
}
};
/*
题解2(利用二分查找)
二分需要注意的点:
循环退出条件、mid 的取值,low 和 high 的更新
low 设置为1根开始,high 设置为piles的最大值;
mid = (low + high) / 2;
循环推出条件:low >= high;
利用enoughEat 方法,判断H(有效时间内)能否吃完;
能吃完,则将mid 赋值给 high,否则low = mid + 1;
*/
const enoughEat = function enoughEat(piles, speed, H){
let resH = 0;
piles.forEach(item => {
resH += Math.ceil(item / speed)
});
return resH <= H;
}
var minEatingSpeed = function(piles, H) {
let low = 1;
let high = Math.max(...piles);
while(low < high){
let mid = Math.floor((low + high) / 2);
if(enoughEat(piles, mid, H)){
high = mid;
}else{
low = mid + 1;
}
}
return high;
} |
第一次参与,加油
};` |
var minEatingSpeed = function (piles, H) {
// res 的取值范围:[piles.length, Math.max(piles)] 双闭区间
// 二分法从最大的
if (piles.length == 1) {
return Math.ceil(piles[0] / H);
}
var res;
var len = piles.length;
var resMin = piles.length;
var resMax = Math.max(...piles);
piles.sort((a, b) => b - a)
// 二分法 resMin ~ resMax
let mid
while (resMax > resMin) {
let mid = resMin + Math.ceil((resMax - resMin) / 2);
let count = 0;
piles.forEach(o => {
count += Math.ceil(o / mid);
})
if (count == H) {
for (var i = resMin; i <= mid; i++) {
let _c = 0
piles.forEach(o => {
_c += Math.ceil(o / i);
})
if (_c <= H) {
return i
}
}
return mid
} else if (count > H) {
resMin = mid
} else if (count < H) {
resMax = mid
}
}
return resMin
}; 超出时间限制,但是记录一下吧 |
|
var minEatingSpeed = function(piles, h) {
let low = 0, high = Math.max(...piles)
let mid
while(high - low > 1) {
mid = Math.floor((low+high)/2)
let sum = 0
for(let i of piles) {
sum = sum + Math.ceil(i/mid)
}
if(sum > h) low = mid
else high = mid
}
return high
}; |
var minEatingSpeed = function(piles, h) {
}; |
珂珂喜欢吃香蕉。这里有
N
堆香蕉,第i
堆中有piles[i]
根香蕉。警卫已经离开了,将在H
小时后回来。珂珂可以决定她吃香蕉的速度
K
(单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉K
根。如果这堆香蕉少于K
根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。
返回她可以在
H
小时内吃掉所有香蕉的最小速度K
(K 为整数)。示例 1:
示例 2:
示例 3:
提示:
1 <= piles.length <= 10^4
piles.length <= H <= 10^9
1 <= piles[i] <= 10^9
附赠leetcode地址:leetcode
The text was updated successfully, but these errors were encountered: