📜  可可吃香蕉

📅  最后修改于: 2022-05-13 01:56:08.620000             🧑  作者: Mango

可可吃香蕉

给定N堆香蕉,第 i 堆有堆[i] 根香蕉和H小时的时间,直到警卫返回 (N < H)。找出每小时最少吃的 ( S ) 个香蕉,这样 Koko 可以在H小时内吃完所有的香蕉。每个小时,Koko 都会选择一堆香蕉,然后从那堆香蕉中吃掉S根香蕉。如果这堆香蕉的数量少于S ,那么她会吃掉所有的香蕉,并且在那一小时内不会再吃任何香蕉。

例子:

幼稚的方法: 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)