DSA · Topic 5 of 18 · Core Structures

Binary Search

Sorted, or 'yes, yes, yes, no, no'? Check the middle and throw half away.

7 problems · O(log n), or O(n log(range)) when each check costs O(n) time, O(1) space

Step 1 Understand it

Remember it by

Sorted, or 'yes, yes, yes, no, no'? Check the middle and throw half away.

Watch it happen

AnimationBinary search: each look throws away half of what is left
Read the animation as text
  1. The array is sorted. Keep a range [lo, hi] that must contain the target, and look at the middle.
  2. mid = (0 + 5) // 2 = 2, value 3. 3 < 9, and the array is sorted, so everything left of mid is too small as well.
  3. Throw away the whole left half in one step: lo = mid + 1 = 3. Half the array gone with one comparison.
  4. mid = (3 + 5) // 2 = 4, value 9. Found it: answer 4.
  5. Two looks instead of five. Each look halves the range, so n items take about log₂ n looks: a million items, about 20.

The idea

If you can ask a yes/no question whose answers flip only once across a range (sorted values, or 'is speed k fast enough?'), test the middle and discard the half that can't contain the answer. Each step halves the range: O(log n).

Picture it

flowchart LR
  R["range lo … hi"] --> M["mid = (lo + hi) // 2"]
  M --> Q{"does mid work?"}
  Q -->|"yes"| H["keep the left half<br/>hi = mid"]
  Q -->|"no"| L["keep the right half<br/>lo = mid + 1"]
  H & L --> C{"lo == hi?"}
  C -->|"no"| M
  C -->|"yes"| A["answer = lo"]
Each check throws away half of what's left.

Analogy

Guessing a number from 1 to 100 with 'higher or lower' hints. Always guess the middle and you need at most 7 guesses.

Where the analogy breaks

The guessing game always has a number. Binary search on the answer needs a range of possible answers and a check that flips exactly once — you have to design that check yourself.

More detail

What it is

If you're looking for the word 'Elephant' in a physical dictionary, you don't start at page 1 and read every single word. You open the book to the exact middle. If you see 'Monkey', you know 'Elephant' must be in the left half, so you rip the book in half and throw away the right side. You repeat this until you find it! Binary Search is the algorithmic version of this: it dramatically cuts the search space in half with every single step.

When to use it

  • When the array is ALREADY SORTED.
  • When the problem asks for an O(log N) runtime explicitly.
  • When you are searching for a specific target value or condition.
  • When the problem involves a continuous range of numbers (e.g., 'find the minimum capacity').

How it works

You set left = 0 and right = array.length - 1. You enter a loop while (left <= right). You calculate the exact middle index (mid = left + (right - left) / 2). If array[mid] is exactly what you want, you win! If array[mid] is too small, you search the right half (left = mid + 1). If it's too big, you search the left half (right = mid - 1).

Example walkthrough

Input: nums = [-1,0,3,5,9,12], target = 9

  1. left=0, right=5. mid=2 (nums[2] is 3). 3 is less than 9. Throw away left half. left=3.
  2. left=3, right=5. mid=4 (nums[4] is 9). 9 equals target! We found it at index 4.

Result: 4

Related patterns

  • Two Pointers: Binary Search literally uses two pointers to represent the search boundaries.

Step 2 Recognise it

Words that signal it

  • Sorted array or matrix; 'O(log n)' required
  • 'Minimum speed / capacity / time such that …' (search on the answer)
  • 'Rotated sorted array'
  • 'Find the first / last position where …'

Don't confuse it with

  • Two Pointers: Sorted and looking for a pair → two pointers. Sorted and looking for one position or threshold → binary search.
  • Greedy / linear scan: If checking one candidate answer is easy but the answer range is huge, binary search the answer instead of trying them all.

Gut check

Can I ask 'is the answer ≤ mid?' and get yes/no that flips once? → binary search.

How to recognise it in an interview

The input array is explicitly marked 'sorted' and requires 'Fast', 'Optimized', or 'O(log N)' search.

Step 3 The template

The general shape. Adapt it to each problem rather than learning one solution per problem.

python
def binary_search_on_answer(lo, hi):
    # find the smallest value in [lo, hi] for which ok(value) is True
    while lo < hi:
        mid = (lo + hi) // 2
        if ok(mid):        # mid works -> the answer is mid or smaller
            hi = mid
        else:              # mid fails -> the answer is bigger
            lo = mid + 1
    return lo

def ok(value):
    ...                    # your yes/no check
The same template in Java
text
class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }
}
TimeO(log n), or O(n log(range)) when each check costs O(n)
SpaceO(1)

Common mistakes

  • Infinite loops: with while lo < hi, set hi = mid (not mid − 1) and lo = mid + 1.
  • Using lo <= hi with hi = mid, which loops forever when lo == hi.
  • Searching the answer space without checking the check really flips only once.
  • Calculating mid as (left + right) / 2, which can cause a serious integer overflow if the array is massive. Always use left + (right - left) / 2.

Step 4 Watch it run

Two problems, traced step by step exactly as the code runs.

Easy example: Binary Search

Input: nums = [-1, 0, 3, 5, 9, 12], target = 9

lohimidaction
052 (value 3)too small → search right half
354 (value 9)found it

Result: 4

Notice: Six items, found in two checks. A million items would take about 20.

python
def search(nums, target):
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if nums[mid] == target:
            return mid
        if nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

Medium example: Koko Eating Bananas (search on the answer)

Input: piles = [3, 6, 7, 11], h = 8

lohispeed khours neededdecision
11166 hoursfast enough → try slower (hi = k)
16310 hourstoo slow → need faster (lo = k + 1)
4658 hoursfast enough → try slower (hi = k)
4548 hoursfast enough → try slower (hi = k)

Result: 4

Notice: There's no sorted array here. The sorted thing is the answer space: slow speeds fail, fast speeds pass, and binary search finds the switch point.

python
import math

def min_eating_speed(piles, h):
    lo, hi = 1, max(piles)
    while lo < hi:
        k = (lo + hi) // 2
        hours = sum(math.ceil(p / k) for p in piles)
        if hours <= h:
            hi = k            # fast enough: try slower
        else:
            lo = k + 1        # too slow: go faster
    return lo

Step 5 Practise

Read each question and say the pattern and the trick out loud before you open the answer. Then solve it on LeetCode. Tick a problem once you've solved it on your own: it comes back for review tomorrow, then after 3, 7, 14 and 30 days, then every month, on the DSA page.

Easy

Medium

  1. Search a 2D Matrix Medium

    Search a matrix whose rows are sorted and each row starts after the previous one ends.

    Show answer

    Technique: Binary search on a flattened index

    The clue: The whole matrix is one sorted list in disguise.

    The trick: Binary search index 0 … m·n − 1, mapping mid to row mid // n and column mid % n.

  2. Koko Eating Bananas Medium

    Find the slowest eating speed that finishes all banana piles within h hours.

    Show answer

    Technique: Binary search on the answer

    The clue: 'Minimum speed such that …' — slow speeds fail, fast speeds pass.

    The trick: Search speeds 1 … max(piles); hours = sum of ceil(pile / k); keep the smallest speed that fits.

  3. Find Minimum In Rotated Sorted Array Medium

    Find the smallest number in a sorted array that has been rotated.

    Show answer

    Technique: Binary search comparing with the right end

    The clue: Sorted but rotated, O(log n).

    The trick: If nums[mid] > nums[right], the minimum is right of mid; otherwise it's at mid or to its left.

  4. Search In Rotated Sorted Array Medium

    Find a target in a rotated sorted array in O(log n).

    Show answer

    Technique: Binary search, find the sorted half

    The clue: Sorted but rotated, O(log n).

    The trick: One half around mid is always sorted; check whether the target lies inside that half to decide where to go.

  5. Time Based Key Value Store Medium

    Store values with timestamps and return the latest value at or before a given time.

    Show answer

    Technique: Hash map + binary search on timestamps

    The clue: Timestamps arrive in increasing order, and you need 'the last one ≤ t'.

    The trick: Map each key to a list of (time, value); binary search for the rightmost time ≤ t.

Hard

  1. Median of Two Sorted Arrays Hard

    Find the median of two sorted arrays in O(log(m + n)).

    Show answer

    Technique: Binary search on a partition

    The clue: Two sorted arrays and a log-time requirement.

    The trick: Binary search how many items to take from the smaller array so that the left halves together hold half the items and every left item ≤ every right item.

What to say in the interview

'Because the array is already sorted, I can optimize the search from O(N) to O(log N) by using Binary Search.'

Follow-up prep

Can you use Binary Search on a Rotated Array?