Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 9 – Binary search

Search on the answer: capacity and speed

Find the slowest speed or the smallest capacity that still finishes in time by binary searching the answer itself with a yes-or-no check of each guess.

  • Intermediate
  • 25 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0, Java 25, Clang 21.0.0 and Go 1.27.1
  • By MySmartCoPilot
Free intro, Pro: 6 of 25 minutes free
Free: The problem: the slowest speed that finishes the revision. With a pass: the other 10 sections and 3 interview answers, about 19 minutes.

What you will learn

  • Convert "the smallest speed or capacity that finishes in time" into a yes-or-no check and search its values
  • Set search bounds that surely contain the answer and leave out speeds that cannot work
  • Write the feasibility check in O(n) with exact integer arithmetic
  • Explain when the totals of the check overflow 32 bits, and size them for 64 bits

Before you start

What you’ll learn · Before you start

What you will learn

  • Convert "the smallest speed or capacity that finishes in time" into a yes-or-no check and search its values
  • Set search bounds that surely contain the answer and leave out speeds that cannot work
  • Write the feasibility check in O(n) with exact integer arithmetic
  • Explain when the totals of the check overflow 32 bits, and size them for 64 bits

Before you start

On this page

Search on the answer means binary searching the possible answers themselves instead of positions in the input. It fits questions of the form “what is the smallest speed, or the smallest capacity, that still finishes in time?”. Pick a guess, check it with one pass over the input, and use the verdict to discard half of the remaining guesses: if speed s finishes in time, every faster speed does too, and if it does not, no slower speed can. With answers up to 10⁹ that takes about 30 checks. What follows is an original version of the task widely called Koko eating bananas, a count of what the brute force would take at its limits, and the signal that points to this search.

The problem: the slowest speed that finishes the revision

The problem

A student has n chapters left to revise before an exam, chapter i with pages[i] pages, and h hours to do it. The student picks one reading speed, s pages an hour, a whole number, and works hour by hour: each hour goes to one chapter and covers up to s of its remaining pages. When fewer than s pages of a chapter are left, they are finished in that hour and the rest of the hour is a break, so no hour is shared by two chapters. Return the slowest speed that finishes every chapter within h hours. Limits: 1 ≤ n ≤ 10⁵, n ≤ h ≤ 10⁹ and 1 ≤ pages[i] ≤ 10⁹.

  1. pages = [12, 7, 30, 18] and h = 8 give 10: at 10 pages an hour the chapters take 2 + 1 + 3 + 2 = 8 hours, and at 9 they would take 9.
  2. The same chapters with h = 4 give 30: one hour per chapter, so the speed must cover the longest chapter.
  3. One chapter of 1,000,000,000 pages with h = 3 gives 333,333,334.
Bars of hours needed for speeds 5 to 16 fall from 15 to 6; a dashed line marks h = 8; speed 10 is the first bar at or under it.Hours needed at each speed, pages 12, 7, 30, 18081515512611710899810811712713714615616h = 8first speed that fits: 10speed, in pages an hourThe hours never rise as the speed grows, so "fits" flips once

Hours needed never rise as the speed grows

Text description of the diagram

The chart shows, for the chapters of 12, 7, 30 and 18 pages, how many hours each reading speed from 5 to 16 pages an hour needs, with each count written at the foot of its bar. The bars read 15, 12, 11, 10, 9, 8, 8, 7, 7, 7, 6 and 6 hours: they fall or stay level, and never rise.

A dashed horizontal line marks h = 8 hours. The bars for speeds 5 to 9 are above the line and are drawn plain; the bars from speed 10 on are at or under it and are highlighted. An arrow labelled "first speed that fits: 10" points at the bar for speed 10.

The note at the bottom says that because the hours never rise as the speed grows, the question "does it fit in h hours?" flips once, from no to yes.

The brute force: try every speed

Try s = 1, 2, 3 and so on, add up the hours each speed needs, ⌈p / s⌉ for every chapter, and stop at the first speed that fits. Each try is one pass over the chapters, but the answer can be as large as 10⁹, so the tries can number 10⁹ and the work 10¹⁴:

Trying speeds one by one, and what one try costs at the limits Python · brute/try_speeds.py
"""The slowest reading speed, found by trying 1, 2, 3, ... pages an hour: the brute force, with its tries counted."""
import random
import time


def hours_needed(pages, speed):
    """Each hour goes to one chapter, so a chapter of p pages takes ceil(p / speed) hours."""
    return sum(-(-p // speed) for p in pages)


def slowest_by_trying(pages, h):
    speed = 1
    while hours_needed(pages, speed) > h:
        speed += 1
    return speed  # the speed is also the number of tries


for pages, h in [([12, 7, 30, 18], 8), ([12, 7, 30, 18], 4), ([1_000, 2_000], 3)]:
    speed = slowest_by_trying(pages, h)
    print(f"{pages}, h = {h}: speed {speed:,} after {speed:,} tries")

# One try at the limits: 100,000 chapters of up to a billion pages each.
rng = random.Random(2)
chapters = [rng.randint(1, 10**9) for _ in range(100_000)]
start = time.perf_counter()
for speed in (1, 1_000, 1_000_000):
    hours_needed(chapters, speed)
per_try = (time.perf_counter() - start) / 3
print(f"one try over 100,000 chapters: about {per_try * 1000:,.0f} ms")
print(f"an answer near 10^9 needs about 10^9 tries: about {per_try * 10**9 / 86_400 / 365:,.1f} years")

Output

[12, 7, 30, 18], h = 8: speed 10 after 10 tries
[12, 7, 30, 18], h = 4: speed 30 after 30 tries
[1000, 2000], h = 3: speed 1,000 after 1,000 tries
one try over 100,000 chapters: about 7 ms
an answer near 10^9 needs about 10^9 tries: about 0.2 years

This output changes from run to run: the times depend on the computer and on what else it is doing

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 try_speeds.py

One try over 100,000 chapters takes milliseconds, and a billion of them would take months or years, where the time limit is a second or two.

What to notice

A faster speed never needs more hours: each chapter’s ⌈p / s⌉ can only fall or stay the same as s grows. So “finishes within h hours” is false for slow speeds and true from one speed on, a condition that flips once along the speeds 1 to 10⁹. Capacity behaves the same way: a bigger van never needs more days to carry the same parcels in the same order. The input does not need to be sorted or searched at all: the thing to search is the answer.

The slowest speed by halving, step by step Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • Why a faster speed never needs more hours: the proof
  • The search in five languages
  • An hours total that overflows 32 bits, reproduced
  • Rounding up without floating point
  • The same search for capacity: shipping parcels within d days
  • Edge cases, variants and follow-ups
    • Edge cases and common bugs
    • Variants, with answers
    • Follow-up questions, answered
  • Practise: the earliest minute the ovens finish the order
    • The earliest minute the ovens finish the order
  • Check yourself
  • Interview questions
    • Your Java solution for the slowest reading speed keeps the total hours in an int and passed every test. When the limit on h is raised from 10⁹ to 2 × 10⁹, a test with 100,000 chapters of 10⁹ pages gets speed 1. Explain the failure, and why the old limits hid it.
    • For the slowest reading speed, a teammate searches the speeds from 0 to 10⁹. What can go wrong at each end? Give tight bounds with a reason for each, and say how many checks they save for 10⁵ chapters of 10⁹ pages each with h = 2 × 10⁵.
    • Change one rule of the reading-speed problem at a time. An hour may continue with the next chapter. Each chapter may be read at its own speed, and you minimise the fastest one. Or h becomes a number of days of at most 8 hours, and a chapter may continue the next day. Which changes still need a binary search?
  • Key takeaways

4 runnable examples (C++, Go, Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 23 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.