Skip to content
Back to Home

Binary Search

4 core · 10 optional problemsInteractive visual guide

Binary search finds a boundary in an ordered candidate space. The key is a monotonic predicate: once a candidate is classified as “after,” every later candidate must also be “after.”

1. The Transition-Point Recipe

Reframe the search space as two monotonic regions:

before  before  before  before | after  after  after
                                ^
                          transition point

Define is_before(x) so every “before” candidate comes before every “after” candidate. The values themselves do not need to be booleans; only this classification must be monotonic.

python
def first_after(first, last, is_before):
    if first > last or not is_before(first):
        return first
    if is_before(last):
        return last + 1
    left, right = first, last
    while right - left > 1:
        mid = left + (right - left) // 2
        if is_before(mid):
            left = mid
        else:
            right = mid
    return right

The loop never changes:

  • left remains known “before,” and right remains known “after.”
  • mid is strictly between them, so every iteration makes progress.
  • When they are adjacent, left and right identify the transition.

The function searches inclusive integer bounds [first,last] and returns the first after index, or last+1 if all candidates are before. Empty input returns first. For a lower bound, call first_after(0, len(nums)-1, lambda i: nums[i] < target); check the returned index is in bounds before checking equality. For an upper bound, use nums[i] <= target instead. Subtract lower from upper to count occurrences.

2. Translate the Task into a Predicate

Task“Before” conditionReturned boundary
First positive value in a sorted arraynums[i] <= 0First positive index, or n if absent
Minimum of a nonempty rotated sorted array with distinct valuesnums[i] > nums[-1]Start of the lower-valued suffix; index zero if unrotated
Smallest capacity that permits at most k groupsgroups_needed(capacity) > kFirst feasible capacity within the chosen bounds

For the rotated minimum, values before the pivot exceed the last value and values from the pivot onward do not. Duplicates can destroy that separation: [1,0,1] is a counterexample. For capacity search, proving that required group count never increases with capacity is part of the solution, not an assumption supplied by the binary-search loop.

3. Reusable Idea: Grid Flattening

If an R x C grid is sorted in complete row-major order, imagine it as one virtual sorted array of length R * C. Do not allocate that array; translate indices only when reading a cell:

  • Grid to virtual index: i = r * C + c.
  • Virtual index to grid: r = i // C, c = i % C.

This produces an O(log⁡(RC))O(\log(RC)) search with O(1)O(1) extra space. It is valid only when each row is sorted and the last value of one row is smaller than the first value of the next row.

4. Reusable Idea: Exponential Search and Guess-and-Check

When a search range has no known upper bound, probe 1, 2, 4, 8, ... until the predicate changes. The last two probes bracket the transition; then apply the normal recipe inside that interval.

left, right = 0, 1
while is_before(right):
    left = right
    right *= 2

# The transition is now in (left, right].
answer = first_after(left, right, is_before)

This pairs naturally with guess-and-check:

  1. Guess a candidate answer.
  2. Check whether it is too small, too large, feasible, or infeasible.
  3. Prove those answers form one monotonic transition.
  4. Binary search for the first or last candidate that satisfies the constraint.

Use this when checking one candidate is much easier than constructing the optimum directly. If the answer bounds are unknown, exponential search can discover them first.

5. Complexity and Key Takeaways

A range of N candidates needs O(log⁡(N+1))O(\log(N+1)) predicate evaluations. If a feasibility check scans n items, total time is O(nlog⁡(N+1))O(n\log(N+1)), not just logarithmic. Auxiliary space includes whatever the predicate allocates.

  • State the first-after return convention and check the last+1 sentinel before indexing.
  • Empty, all-before, all-after, one-item and duplicate-heavy inputs must follow the same contract.
  • A globally sorted flattened grid works; a grid with only each row sorted does not give one global transition.
  • Repeated doubling needs a guaranteed finite transition or a known limit. Handle index overflow and out-of-range probes; otherwise bound discovery may never stop.

For splitting a nonnegative array into at most k groups while minimizing the maximum group sum, a guessed capacity can be checked by greedily filling each group. More capacity never requires more groups, so binary search can find the smallest feasible capacity. Prove that monotonicity for each new problem; an arbitrary local trend or a rotated array with ambiguous duplicates may require different handling.

Continue to Two Pointers when candidates can be eliminated one at a time, Sorting to establish order, and Dynamic Programming when a feasibility check itself has overlapping subproblems.

Practice Problems

Optional Variations (10)

Choose a variation when you want to explore a specific pattern. These are not required before moving to the next topic.

Find Minimum in Rotated Sorted Array

Medium

Suppose an array of length n sorted in ascending order is rotated between 1 and n times. Given the rotated array nums of unique elements, return the minimum element.

Start Solving

Valley Bottom

Medium

A valley-shaped array is an array of integers such that:

Start Solving

2-Array 2-Sum

Medium

You are given two non-empty arrays of integers, sorted_arr and unsorted_arr. The first one is sorted, but the second is not. The goal is to find one element from each array with sum 0. If you can find them, return an array with their indices, starting with the element in sorted_arr. Otherwise, return [-1, -1]. Use O(1) extra space and do not modify the input.

Start Solving

Target Count Divisible By K

Medium

Given a sorted array of integers, arr, a target value, target, and a positive integer, k, return whether the number of occurrences of the target in the array is a multiple of k.

Start Solving

Race Overtaking

Medium

You are given two arrays of positive integers, p1 and p2, representing players in a racing game. The two arrays are sorted, non-empty, and have the same length, n. The i-th element of each array corresponds to where that player was on the track at the i-th second of the race. We know that:

Start Solving

Search in Sorted Grid

Medium

You're given a 2D grid of integers, grid, where each row is sorted (without duplicates), and the last value in each row is smaller than the first value in the following row. You are also given a target value, target. If the target is in the grid, return an array with its row and column indices. Otherwise, return [-1, -1].

Start Solving

Search in Huge Array

Medium

We are trying to search for a target integer, target, in a sorted array of integers (duplicates allowed) that is too big to fit into memory. We can only access the array through an API, fetch(i), which returns the value at index i if i is within bounds or -1 otherwise. Using as few calls to the API as possible, return the index of the target, or -1 if it does not exist. If the target appears multiple times, return any of the indices. There is no API to get the array's length.

Start Solving

Water Refilling

Medium

We have an empty container with a capacity of a gallons of water and another container with a capacity of b gallons. Return how many times you can pour the second container full of water into the first one without overflowing. Assume that a > b.

Start Solving

Min Pages Per Day

Medium

You have upcoming interviews and have selected specific chapters from BCtCI to read beforehand. Given an array, page_counts, where each element represents a chapter's page count, and the number of days, days, until your interview, determine the minimum number of pages you must read daily to finish on time. Assume that:

Start Solving

Tide Aerial View

Medium

You are provided a series of aerial-view pictures of the same coastal region, taken a few minutes apart. Each picture consists of an n x n binary grid, where 0 represents land (above water) and 1 represents water (below water).

Start Solving