A monkey is given n piles of bananas, where the 'ith' pile has nums[i] bananas. An integer h represents the total time in hours to eat all the bananas.
Each hour, the monkey chooses a non-empty pile of bananas and eats k bananas. If the pile contains fewer than k bananas, the monkey eats all the bananas in that pile and does not consume any more bananas in that hour.
Determine the minimum number of bananas the monkey must eat per hour to finish all the bananas within h hours.
Input: n = 4, nums = [7, 15, 6, 3], h = 8
Output: 5
Explanation: If Koko eats 5 bananas/hr, he will take 2, 3, 2, and 1 hour to eat the piles accordingly. So, he will take 8 hours to complete all the piles.
Input: n = 5, nums = [25, 12, 8, 14, 19], h = 5
Output: 25
Explanation: If Koko eats 25 bananas/hr, he will take 1, 1, 1, 1, and 1 hour to eat the piles accordingly. So, he will take 5 hours to complete all the piles.
Input: n = 4, nums = [3, 7, 6, 11], h = 8
The straightforward solution for this problem is to use linear search algorithm to to check all possible answers from 1 to max, where max is the maximum element of the array. The minimum number for which the required time is less than or equal to h, is our required answer.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
// Helper function to find the maximum element in the vector
int findMax(vector<int> &v) {
int maxi = INT_MIN;
int n = v.size();
// Find the maximum element
for (int i = 0; i < n; i++) {
maxi = max(maxi, v[i]);
}
return maxi;
}
/* Helper function to calculate total hours
required at given hourly rate */
long long calculateTotalHours(vector<int> &v, int hourly) {
long long totalH = 0;
int n = v.size();
// Calculate total hours required
for (int i = 0; i < n; i++) {
totalH += ceil((double)(v[i]) / (double)(hourly));
}
return totalH;
}
public:
// Function to find the minimum rate to eat bananas
int minimumRateToEatBananas(vector<int> nums, int h) {
// Find the maximum number of bananas
int maxi = findMax(nums);
/* Find the minimum value of k
that satisfies the condition*/
for (int i = 1; i <= maxi; i++) {
long long reqTime = calculateTotalHours(nums, i);
if (reqTime <= (long long)h) {
return i;
}
}
/* Dummy return statement (should
not be reached in valid cases)*/
return maxi;
}
};
int main() {
vector<int> v = {7, 15, 6, 3};
int h = 8;
// Create an object of the Solution class
Solution sol;
int ans = sol.minimumRateToEatBananas(v, h);
// Print the result
cout << "Koko should eat at least " << ans << " bananas/hr.\n";
return 0;
}
import java.util.*;
class Solution {
// Helper function to find the maximum element in the array
private int findMax(int[] v) {
int maxi = Integer.MIN_VALUE;
int n = v.length;
// Find the maximum element
for (int i = 0; i < n; i++) {
maxi = Math.max(maxi, v[i]);
}
return maxi;
}
/* Helper function to calculate total hours
required at given hourly rate */
private long calculateTotalHours(int[] v, int hourly) {
long totalH = 0;
int n = v.length;
// Calculate total hours required
for (int i = 0; i < n; i++) {
totalH += Math.ceil((double) v[i] / (double) hourly);
}
return totalH;
}
// Function to find the minimum rate to eat bananas
public int minimumRateToEatBananas(int[] nums, int h) {
// Find the maximum number of bananas
int maxi = findMax(nums);
/* Find the minimum value of k
that satisfies the condition */
for (int i = 1; i <= maxi; i++) {
long reqTime = calculateTotalHours(nums, i);
if (reqTime <= (long) h) {
return i;
}
}
/* Dummy return statement (should
not be reached in valid cases) */
return maxi;
}
}
class Main {
public static void main(String[] args) {
int[] v = {7, 15, 6, 3};
int h = 8;
// Create an object of the Solution class
Solution sol = new Solution();
int ans = sol.minimumRateToEatBananas(v, h);
// Print the result
System.out.println("Koko should eat at least " + ans + " bananas/hr.");
}
}
import math
class Solution:
# Helper function to find the maximum element in the list
def findMax(self, v):
maxi = float('-inf')
n = len(v)
# Find the maximum element
for i in range(n):
maxi = max(maxi, v[i])
return maxi
""" Helper function to calculate total hours
required at given hourly rate """
def calculateTotalHours(self, v, hourly):
totalH = 0
n = len(v)
# Calculate total hours required
for i in range(n):
totalH += math.ceil(v[i] / hourly)
return totalH
# Function to find the minimum rate to eat bananas
def minimumRateToEatBananas(self, nums, h):
# Find the maximum number of bananas
maxi = self.findMax(nums)
""" Find the minimum value of k
that satisfies the condition """
for i in range(1, maxi + 1):
reqTime = self.calculateTotalHours(nums, i)
if reqTime <= h:
return i
""" Dummy return statement (should
not be reached in valid cases) """
return maxi
# Driver Code
if __name__ == "__main__":
v = [7, 15, 6, 3]
h = 8
# Create an object of the Solution class
sol = Solution()
ans = sol.minimumRateToEatBananas(v, h)
# Print the result
print(f"Koko should eat at least {ans} bananas/hr.")
class Solution {
// Helper function to find the maximum element in the array
findMax(v) {
let maxi = Number.MIN_SAFE_INTEGER;
let n = v.length;
// Find the maximum element
for (let i = 0; i < n; i++) {
maxi = Math.max(maxi, v[i]);
}
return maxi;
}
/* Helper function to calculate total hours
required at given hourly rate */
calculateTotalHours(v, hourly) {
let totalH = 0;
let n = v.length;
// Calculate total hours required
for (let i = 0; i < n; i++) {
totalH += Math.ceil(v[i] / hourly);
}
return totalH;
}
// Function to find the minimum rate to eat bananas
minimumRateToEatBananas(nums, h) {
// Find the maximum number of bananas
let maxi = this.findMax(nums);
/* Find the minimum value of k
that satisfies the condition */
for (let i = 1; i <= maxi; i++) {
let reqTime = this.calculateTotalHours(nums, i);
if (reqTime <= h) {
return i;
}
}
/* Dummy return statement (should
not be reached in valid cases) */
return maxi;
}
}
// Driver Code
const v = [7, 15, 6, 3];
const h = 8;
// Create an object of the Solution class
const sol = new Solution();
const ans = sol.minimumRateToEatBananas(v, h);
// Print the result
console.log(`Koko should eat at least ${ans} bananas/hr.`);
The idea here is to use binary search algorithm to solve this problem in a optimized way. Now, the search space will be in the range[1,max], where max is the maximum element in the array because the maximum bananas that the monkey can it per our can be the maximum element of the array. As, the search space is sorted so binary search can be applied for better time complexity.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
/* Helper function to find the
maximum element in the vector */
int findMax(vector<int>& nums) {
int maxi = INT_MIN;
int n = nums.size();
// Find the maximum element
for (int i = 0; i < n; i++) {
maxi = max(maxi, nums[i]);
}
return maxi;
}
/* Helper function to calculate total
hours required at given hourly rate */
int calculateTotalHours(vector<int>& nums, int hourly) {
int totalH = 0;
int n = nums.size();
// Calculate total hours required
for (int i = 0; i < n; i++) {
totalH += ceil((double) nums[i] / (double) hourly);
}
return totalH;
}
public:
/* Function to find the
minimum rate to eat bananas */
int minimumRateToEatBananas(vector<int>& nums, int h) {
// Initialize binary search bounds
int low = 1, high = findMax(nums);
// Apply binary search
while (low <= high) {
int mid = (low + high) / 2;
int totalH = calculateTotalHours(nums, mid);
if (totalH <= h) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
};
int main() {
vector<int> nums = {7, 15, 6, 3};
int h = 8;
// Create an object of the Solution class
Solution sol;
int ans = sol.minimumRateToEatBananas(nums, h);
// Print the result
cout << "Koko should eat at least " << ans << " bananas/hr.\n";
return 0;
}
import java.util.*;
class Solution {
/* Helper function to find the
maximum element in the array*/
private int findMax(int[] nums) {
int maxi = Integer.MIN_VALUE;
int n = nums.length;
// Find the maximum element
for (int i = 0; i < n; i++) {
maxi = Math.max(maxi, nums[i]);
}
return maxi;
}
/* Helper function to calculate total
hours required at given hourly rate*/
private int calculateTotalHours(int[] nums, int hourly) {
int totalH = 0;
int n = nums.length;
// Calculate total hours required
for (int i = 0; i < n; i++) {
totalH += Math.ceil((double) nums[i] / (double) hourly);
}
return totalH;
}
/* Function to find the
minimum rate to eat bananas*/
public int minimumRateToEatBananas(int[] nums, int h) {
// Initialize binary search bounds
int low = 1, high = findMax(nums);
// Apply binary search
while (low <= high) {
int mid = (low + high) / 2;
int totalH = calculateTotalHours(nums, mid);
if (totalH <= h) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
public static void main(String[] args) {
int[] nums = {7, 15, 6, 3};
int h = 8;
// Create an object of the Solution class
Solution sol = new Solution();
int ans = sol.minimumRateToEatBananas(nums, h);
// Print the result
System.out.println("Koko should eat at least " + ans + " bananas/hr.");
}
}
import math
class Solution:
""" Helper function to find the
maximum element in the array"""
def findMax(self, nums):
maxi = float('-inf')
n = len(nums)
# Find the maximum element
for i in range(n):
maxi = max(maxi, nums[i])
return maxi
""" Function to calculate total hours
required at given hourly rate"""
def calculateTotalHours(self, nums, hourly):
totalH = 0
n = len(nums)
# Calculate total hours required
for i in range(n):
totalH += math.ceil(nums[i] / hourly)
return totalH
""" Function to find the
minimum rate to eat bananas"""
def minimumRateToEatBananas(self, nums, h):
# Initialize binary search bounds
low, high = 1, self.findMax(nums)
# Apply binary search
while low <= high:
mid = (low + high) // 2
totalH = self.calculateTotalHours(nums, mid)
if totalH <= h:
high = mid - 1
else:
low = mid + 1
return low
if __name__ == "__main__":
nums = [7, 15, 6, 3]
h = 8
# Create an object of the Solution class
sol = Solution()
ans = sol.minimumRateToEatBananas(nums, h)
# Print the result
print(f"Koko should eat at least {ans} bananas/hr.")
class Solution {
/* Helper function to find the
maximum element in the array */
findMax(nums) {
let maxi = Number.MIN_SAFE_INTEGER;
const n = nums.length;
// Find the maximum element
for (let i = 0; i < n; i++) {
maxi = Math.max(maxi, nums[i]);
}
return maxi;
}
/*Helper function to calculate total
hours required at given hourly rate*/
calculateTotalHours(nums, hourly) {
let totalH = 0;
const n = nums.length;
// Calculate total hours required
for (let i = 0; i < n; i++) {
totalH += Math.ceil(nums[i] / hourly);
}
return totalH;
}
/* Function to find the
minimum rate to eat bananas*/
minimumRateToEatBananas(nums, h) {
// Initialize binary search bounds
let low = 1, high = this.findMax(nums);
// Apply binary search
while (low <= high) {
const mid = Math.floor((low + high) / 2);
const totalH = this.calculateTotalHours(nums, mid);
if (totalH <= h) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
}
const nums = [7, 15, 6, 3];
const h = 8;
//Create an instance of Solution class
const sol = new Solution();
const ans = sol.minimumRateToEatBananas(nums, h);
// Print the result
console.log(`Koko should eat at least ${ans} bananas/hr.`);
Q: What if the total hours required exceeds h?
A: If the hours exceed h for a given k, k is too small, and the monkey needs to eat faster. Adjust the binary search range by setting low=mid+1.
Q: How do we handle very large values of nums[i] or h?
A: Use (nums[i]+k−1)//k instead of floating-point division to avoid precision issues and maintain integer operations. This ensures accuracy even with large inputs.
Q: How would you extend this for varying hourly capacities?
A: If the monkey’s eating rate changes per hour (e.g., k depends on the hour), use a dynamic approach to calculate the minimum k for each hour, adjusting the binary search to consider these variations.
Q: What if the piles of bananas can be replenished?
A: For dynamic or replenishing piles, track the rate of replenishment and modify the binary search to account for the changing size of nums[i] at each hour.