可可吃香蕉
给定N堆香蕉,第 i 堆有堆[i] 根香蕉和H小时的时间,直到警卫返回 (N < H)。找出每小时最少吃的 ( S ) 个香蕉,这样 Koko 可以在H小时内吃完所有的香蕉。每个小时,Koko 都会选择一堆香蕉,然后从那堆香蕉中吃掉S根香蕉。如果这堆香蕉的数量少于S ,那么她会吃掉所有的香蕉,并且在那一小时内不会再吃任何香蕉。
例子:
Input: piles = [3, 6, 7, 11], H = 8
Output: 4
Explanation: Koko will eat 4 bananas per hour to finish all the bananas
Input: piles = [30, 11, 23, 4, 20], H = 6
Output: 23
Explanation: Koko will eat 23 bananas per hour to finish all the bananas
幼稚的方法: Koko 必须每小时至少吃一根香蕉。让下界为start 。 Koko在一小时内可以吃的香蕉的最大数量是所有香蕉堆的最大数量。这是S的最大可能值。让上限结束。具有从开始到结束的搜索间隔并使用线性搜索,对于S的每个值,可以检查这个吃香蕉的速度是否有效。 S的第一个有效值将是最慢的速度和所需的答案。
时间复杂度: O(N * W),其中W是所有堆中的最大香蕉
方法:给定的问题可以通过对答案技术使用二分搜索来有效地解决:
- 创建一个布尔函数来检查选择的速度(香蕉/小时)是否足以在给定的H小时时间内吃完所有香蕉
- S的下限是 1 根香蕉/小时,因为 Koko 必须每小时吃一根香蕉,而上限是所有堆的最大香蕉
- 对可能的答案范围应用二进制搜索以获得 S 的最小值
- 如果布尔函数满足中间值,则降低到中间值
- 否则将下限更新为 mid + 1
C++
// C++ implementation for the above approach
#include
using namespace std;
bool check(vector& bananas, int mid_val, int H)
{
int time = 0;
for (int i = 0; i < bananas.size(); i++) {
// to get the ceil value
if (bananas[i] % mid_val != 0) {
// in case of odd number
time += ((bananas[i] / mid_val) + 1);
}
else {
// in case of even number
time += (bananas[i] / mid_val);
}
}
// check if time is less than
// or equals to given hour
if (time <= H) {
return true;
}
else {
return false;
}
}
int minEatingSpeed(vector& piles, int H)
{
// as minimum speed of eating must be 1
int start = 1;
// Maximum speed of eating
// is the maximum bananas in given piles
int end = *max_element(piles.begin(), piles.end());
while (start < end) {
int mid = start + (end - start) / 2;
// Check if the mid(hours) is valid
if ((check(piles, mid, H)) == true) {
// If valid continue to search
// lower speed
end = mid;
}
else {
// If cant finish bananas in given
// hours, then increase the speed
start = mid + 1;
}
}
return end;
}
// Driver code
int main()
{
vector piles = { 30, 11, 23, 4, 20 };
int H = 6;
cout << minEatingSpeed(piles, H);
return 0;
}
Java
// Java implementation for the above approach
import java.util.*;
class GFG{
static boolean check(int[] bananas, int mid_val, int H)
{
int time = 0;
for (int i = 0; i < bananas.length; i++) {
// to get the ceil value
if (bananas[i] % mid_val != 0) {
// in case of odd number
time += ((bananas[i] / mid_val) + 1);
}
else {
// in case of even number
time += (bananas[i] / mid_val);
}
}
// check if time is less than
// or equals to given hour
if (time <= H) {
return true;
}
else {
return false;
}
}
static int minEatingSpeed(int []piles, int H)
{
// as minimum speed of eating must be 1
int start = 1;
// Maximum speed of eating
// is the maximum bananas in given piles
int end = Arrays.stream(piles).max().getAsInt();
while (start < end) {
int mid = start + (end - start) / 2;
// Check if the mid(hours) is valid
if ((check(piles, mid, H)) == true) {
// If valid continue to search
// lower speed
end = mid;
}
else {
// If cant finish bananas in given
// hours, then increase the speed
start = mid + 1;
}
}
return end;
}
// Driver code
public static void main(String[] args)
{
int []piles = { 30, 11, 23, 4, 20 };
int H = 6;
System.out.print(minEatingSpeed(piles, H));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python implementation for the above approach
def check(bananas, mid_val, H):
time = 0;
for i in range(len(bananas)):
# to get the ceil value
if (bananas[i] % mid_val != 0):
# in case of odd number
time += bananas[i] // mid_val + 1;
else:
# in case of even number
time += bananas[i] // mid_val
# check if time is less than
# or equals to given hour
if (time <= H):
return True;
else:
return False;
def minEatingSpeed(piles, H):
# as minimum speed of eating must be 1
start = 1;
# Maximum speed of eating
# is the maximum bananas in given piles
end = sorted(piles.copy(), reverse=True)[0]
while (start < end):
mid = start + (end - start) // 2;
# Check if the mid(hours) is valid
if (check(piles, mid, H) == True):
# If valid continue to search
# lower speed
end = mid;
else:
# If cant finish bananas in given
# hours, then increase the speed
start = mid + 1;
return end;
# Driver code
piles = [30, 11, 23, 4, 20];
H = 6;
print(minEatingSpeed(piles, H));
# This code is contributed by gfgking.
C#
// C# implementation for the above approach
using System;
using System.Linq;
public class GFG{
static bool check(int[] bananas, int mid_val, int H)
{
int time = 0;
for (int i = 0; i < bananas.Length; i++) {
// to get the ceil value
if (bananas[i] % mid_val != 0) {
// in case of odd number
time += ((bananas[i] / mid_val) + 1);
}
else {
// in case of even number
time += (bananas[i] / mid_val);
}
}
// check if time is less than
// or equals to given hour
if (time <= H) {
return true;
}
else {
return false;
}
}
static int minEatingSpeed(int []piles, int H)
{
// as minimum speed of eating must be 1
int start = 1;
// Maximum speed of eating
// is the maximum bananas in given piles
int end = piles.Max();
while (start < end) {
int mid = start + (end - start) / 2;
// Check if the mid(hours) is valid
if ((check(piles, mid, H)) == true) {
// If valid continue to search
// lower speed
end = mid;
}
else {
// If cant finish bananas in given
// hours, then increase the speed
start = mid + 1;
}
}
return end;
}
// Driver code
public static void Main(String[] args)
{
int []piles = { 30, 11, 23, 4, 20 };
int H = 6;
Console.Write(minEatingSpeed(piles, H));
}
}
// This code is contributed by shikhasingrajput
Javascript
23
时间复杂度: O(N log W)(W 是所有堆的最大香蕉数)
辅助空间: O(1)