2Brute2Best
🔥0

Koko Eating Bananas

Medium·LeetCode #875Basic Anchor
LeetCode
30-Second Mental ModelBinary Search on the Answer (minimise speed)
Complexity:O(M · N)→O(N log M)
Key Insight

Every speed is either fast enough or too slow, and once a speed is fast enough, every faster speed is too. So the speeds 1 … max look like ✗✗✗✗✓✓✓✓. Binary search for the first ✓: test the middle speed, and throw away the half that can't hold the answer.

Core Validity Invariant

Speed k is fast enough when Σ ceil(p / k) ≤ h. A faster speed never needs more hours, so the answers look like ✗✗✗✓✓✓ and we search for the first ✓.

01

Problem

Koko has n piles of bananas. Pile i has piles[i] bananas. The guards come back in h hours.

Koko picks one eating speed k (bananas per hour) and keeps it. Every hour she picks one pile and eats k bananas from it. If the pile has fewer than k left, she finishes it and waits for the rest of that hour. She never moves to another pile in the same hour.

Return the smallest integer speed k that lets her finish every pile within h hours.

Input

An integer array piles and an integer h.

Output

One integer: the minimum eating speed.

Example 1
Input: piles = [3, 6, 7, 11], h = 8
Output: 4

At speed 4 the piles take 1 + 2 + 2 + 3 = 8 hours, which fits. At speed 3 they take 1 + 2 + 3 + 4 = 10 hours, which is too many.

Example 2
Input: piles = [30, 11, 23, 4, 20], h = 5
Output: 30

There are 5 piles and only 5 hours, so every pile must be finished in one hour. That needs speed 30, the biggest pile.

Example 3
Input: piles = [30, 11, 23, 4, 20], h = 6
Output: 23

At speed 23 the piles take 2 + 1 + 1 + 1 + 1 = 6 hours. At speed 22 the 23-pile also needs 2 hours, so the total is 7.

Constraints
  • • 1 ≤ piles.length ≤ 10^4
  • • piles.length ≤ h ≤ 10^9
  • • 1 ≤ piles[i] ≤ 10^9
  • • The total hours at a slow speed can reach 10^13 — use a 64-bit type for it.
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    If I tell you a speed, can you quickly work out how many hours Koko needs?

  2. 2.

    How many hours does one pile of p bananas take at speed k? Why is it not just p / k?

  3. 3.

    What is the slowest speed that could make sense? What is a speed that is always fast enough?

  4. 4.

    If speed 5 is fast enough, is speed 6 also fast enough? If speed 5 is too slow, what about speed 4?

  5. 5.

    Do I need to try every speed one by one, or can one check rule out many speeds at once?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceTry speed 1, 2, 3, … and return the first one that finishes in timeO(M · N)O(1)
OptimalBinary search the speed range [1, max]; test each guess with the hours formulaO(N log M)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “smallest speed k such that she finishes in time”"Minimum X such that something is possible" → binary search on the answer X.
  • “if a pile has fewer than k bananas, she waits”Each pile costs ceil(p / k) hours. Given k, the total time is easy to compute → cheap feasibility check.
  • “eating faster never hurts”If k works, k + 1 works. The check is monotonic, so the yes/no answers form ✗✗✗✓✓✓.
Minimise a number+easy check for a fixed guess+check is monotonic→Binary Search on the Answer (minimise speed)

This is the anchor problem for searching the answer space. Nothing in the input is sorted, and we never search the piles array. We search the range of possible speeds, and the check is a simple formula: Σ ceil(p / k) ≤ h. The next problems keep the same shape but change the check: a greedy fill (Ship Packages, Split Array) or counting runs of neighbours (Bouquets).

10

Don't make this mistake

Pattern confusion: binary searching the piles array
✗ sort(piles.begin(), piles.end()); // binary search for some index in piles ...
✓ int lo = 1, hi = *max_element(piles.begin(), piles.end()); // binary search on the speed

The answer is a speed, not a pile. Example 1's answer is 4, which is not even in [3, 6, 7, 11]. We search the range of possible answers, and use the piles only inside the check.

Starting the range at 0
✗ int lo = 0, hi = maxPile;
✓ int lo = 1, hi = maxPile;

Speed 0 makes no sense, and if mid ever becomes 0, p / mid divides by zero and the program crashes. The slowest real speed is 1.

Using p / k (rounding down) for the hours
✗ hours += p / k;
✓ hours += (p + (long long)k - 1) / k; // ceil(p / k)

A pile of 7 at speed 4 takes 2 hours (4, then 3), but 7 / 4 is 1. Integer division rounds down, so you would think slow speeds are fast enough and return an answer that is too small.

Overflowing int
✗ int hours = 0; hours += (p + k - 1) / k;
✓ long long hours = 0; hours += (p + (long long)k - 1) / k;

At speed 1, 10^4 piles of 10^9 bananas need 10^13 hours, far past the int limit (about 2.1·10^9). Even p + k - 1 alone can overflow when both are near 10^9.

Mixing loop styles
✗ while (lo <= hi) { ... hi = mid; ... }
✓ while (lo < hi) { ... hi = mid; else lo = mid + 1; }

With lo <= hi, when lo == hi == mid and mid works, hi = mid changes nothing and the loop never ends. Pick one style: lo < hi with hi = mid, or lo <= hi with hi = mid − 1 and a separate ans variable.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Binary Search translate into production architectures and low-level memory mechanics.