Koko loves to eat bananas. There are n piles of bananas, the ith 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
will not eat any more bananas during this hour.
Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.
Return the minimum integer k such that she can eat all the bananas within h hours.
Example 1:
Input: piles = [3,6,7,11], h = 8
Output: 4
Example 2:
Input: piles = [30,11,23,4,20], h = 5
Output: 30
Example 3:
Input: piles = [30,11,23,4,20], h = 6
Output: 23
Playground: Leetcode 875
Basic Intuition
To eat pile[i] bananas at a rate of k bananas per hour, koko will take ceil(pile[i] / k) hours.

Naive Approach - Linear Search
Start exploring k from 1. For each k, iterate over every pile and calculate the cumulative hours
required to eat all the bananas using ceil(pile / k). Return the first k for which the cumulative
hours are less than or equal to h, as it is the minimum valid eating speed.
Algorithm
1. Initialize "k" to 1.
2. Repeat the following steps until we have an eligible "k".
3. Initialize a variable, "cumHrs" to 0, to store the cumulative hours required to eat
all piles at the rate of "k" bananas per hour.
4. Iterate over each pile and add "ceil(pile / k)" to "cumHrs".
5. If the "cumHrs" is less than or equal to "h", return "k".
6. Otherwise, increment "k" by 1.
Implementation
Time Complexity
For each iteration, we only perform basic arithmetic operations and validation checks, each taking
constant time, O(1). Therefore, the time complexity primarily depends on the number of iterations.
In the worst case, i.e., when h = n, where n = piles.length, the outer loop runs for max(piles) times.
For each iteration, the inner loop traverses all n times.
Since the total iterations is max(piles) x n, the overall time complexity is O(max(piles) x n).
Space Complexity
We use only a variable, cumHrs, to store the cumulative hours required to eat all piles at
a rate of k. Since no additional data structures are used, the overall space complexity is
O(1).
Key Observations
When k >= max(piles), Koko can finish each pile in 1 hour. Therefore, she needs a minimum of
piles.length hours to eat all the piles. For example, if piles = [3, 6, 7, 11], then for any
k >= 11, Koko can finish each pile in 1 hour, requiring a total of 4 hours to eat all the piles.
Hence, we only need to search within the range [1, max(piles)]
to find the minimum rate k
that allows Koko to eat all the bananas within h
hours.

Suitable Approach - Binary Search
The search space [1, max(piles)] follows a monotonic pattern: as the eating speed (k) increases,
the total hours required (cumHrs) to finish all the piles will strictly decrease or stay the same (never
increase).
Because of this:
- If a speed is too slow (
cumHrs > h), we can eliminate that speed and all smaller speeds.

- If a speed is sufficient (
cumHrs <= h), we can eliminate all larger speeds because we're searching for the minimum valid speed.

These observations allow us to use binary search to halve the search space in each iteration until we find the minimum valid eating speed.
Algorithm
1. Initialize:
a. Two pointers, "left = 1" and "right = max(piles)", to define the boundaries of
the search space.
b. A variable, "minimumSpeed = max(piles)" to track the minimum eating speed found
so far.
2. Repeat while the search space is not empty ("left" <= "right"):
3. Calulate the "middle" element in the current search space.
4. Initialize a variable, "totalHours = 0" to track the hours required to eat
all piles at speed "middle".
5. Iterate over each pile and add "ceil(pile / middle)" to "totalHours".
6. If "totalHours" > "h", "middle" is too slow. Move "left" to "middle + 1" to
eliminate "middle" and all smaller speeds.
7. Otherwise, "middle" is a valid candidate. Update "minimumSpeed" to
"middle" and move "right" to "middle - 1" to search for a smaller valid speed.
8. Return "minimumSpeed".
Implementation
Time Complexity
The binary search takes O(logm) iterations, where m = maximum number of bananas in any pile.
In each iteration, we traverse all n piles to calculate the total hours required. Each calculation
takes O(1) time, so each iteration takes O(n) time.
Therefore, the overall time complexity is O(n x logm).
Space Complexity
We use only a fixed number of variables, such as left, right, middle, minimumSpeed, and totalHours.
Since we don't use any additional data structures that grow with input size, the overall space
complexity is O(1).