---
title: 'Binary Search'
description: 'In algorithms, arrays and strings are very similar. They are both ordered collections of elements. The difference is that arrays are mutable, while strings are immutable.'
---
## The idea
You look for a name in a phone book. You do not start at page 1.
You open the middle. Too far? Go left. Not far enough? Go right.
Each step throws away half the book.
100 items → 7 steps. 4 billion items → 32 steps.
**The core rule:** ask a yes/no question that flips exactly once.
Everything left of the flip is "no". Everything right is "yes".
Binary search finds the flip point.
## The picture
```mermaid
flowchart TD
A["Array: 1 3 5 7 9 11 13
Target: 9"] --> B["mid = 7
7 < 9 → discard left half"]
B --> C["Array: 9 11 13
mid = 11
11 > 9 → discard right half"]
C --> D["Array: 9
mid = 9
Found ✓"]
style D fill:#2e7d32,color:#fff
```
## The template
```python
def binary_search(nums: list[int], target: int) -> int:
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
```
## Search the answer space (LC 875 — Koko Eating Bananas)
The array does not need to exist. You can binary search over *possible answers*.
Ask: "does speed k work?" Slow speeds fail. Fast speeds work.
The answer flips once. Find the flip.
```mermaid
flowchart LR
A["k=1
NO"] --> B["k=2
NO"] --> C["k=3
NO"] --> D["k=4
YES ← answer"] --> E["k=5
YES"] --> F["k=6
YES"]
style D fill:#2e7d32,color:#fff
```
```python
import math
def min_eating_speed(piles: list[int], h: int) -> int:
def k_works(k: int) -> bool:
return sum(math.ceil(p / k) for p in piles) <= h
lo, hi = 1, max(piles)
while lo < hi:
mid = (lo + hi) // 2
if k_works(mid):
hi = mid # mid works — keep it, look left
else:
lo = mid + 1 # mid fails — discard it
return lo
```
## Not the same as two pointers
Two pointers **walks** — it inspects every element it passes. O(n).
Binary search **jumps** — it inspects one midpoint and discards half unseen. O(log n).
## Complexity
| | Time | Space |
|---|---|---|
| Sorted array | O(log n) | O(1) |
| Answer space | O(n log m) | O(1) |
n = array size, m = answer range.
## Close-out ritual
Before you submit, say out loud:
1. Time and space complexity.
2. One edge case trace: empty array, one element, or target not present.
## Plan problems
**A-set:** LC 704 · 74 · 875 · 33 · 153
**B-set:** LC 35 · 162 · 34 · 4 ⭐