Pattern #04
Binary Search
EssentialHalve a sorted or monotonic search space until you pin the answer.
When to use
The search space is sorted, rotated-sorted, or any monotonic predicate “feasible(mid)”. not only classic “find target in array”.
Recognition cues
- Sorted array (or partially ordered)
- Find first/last/insert position
- Rotated sorted array
- Peak finding with bitonic property
Common pitfalls
- Infinite loop: use lo < hi with exclusive bound, or lo + 1 < hi carefully
- Mid overflow: prefer lo + ((hi - lo) >> 1)
- Confusing lower-bound vs exact match
90-second recognition drill
Which pattern fits best?
- Sorted array (or partially ordered)
- Find first/last/insert position
- Rotated sorted array
Interactive
Mental model
A full worked walkthrough of the invariant. Pause, scrub the dots, or use ← →. Aim to narrate each step yourself.
Step 1 of 8
-1
lo0
3
5
mid9
12
a[mid] = 5
Half-open search space [lo, hi). Target = 9.
How to think about it
Maintain an interval that must contain the answer. Probe the midpoint; discard half based on a monotonic test. Prefer the lower-bound form: lo = 0, hi = n (exclusive), shrink until lo == hi.
Template checklist
- What is the search space? (indices, values, answer range)
- What does
feasible(mid)mean? - Do you want the first true or last true?
- Handle empty arrays and single-element edge cases.
Complexity baseline
O(log n) time, O(1) space for iterative form.
Template
Same skeleton in TypeScript, Python, and C#. Adapt the invariant; keep the structure.
Binary Search · Template
/** Binary search template: lower-bound, then exact match. */
export function binarySearch(nums: number[], target: number): number {
let lo = 0, hi = nums.length;
while (lo < hi) {
const mid = lo + ((hi - lo) >> 1);
if (nums[mid]! < target) lo = mid + 1;
else hi = mid;
}
return lo < nums.length && nums[lo] === target ? lo : -1;
}
/** Binary search template: lower-bound, then exact match. */
export function binarySearch(nums: number[], target: number): number {
let lo = 0, hi = nums.length;
while (lo < hi) {
const mid = lo + ((hi - lo) >> 1);
if (nums[mid]! < target) lo = mid + 1;
else hi = mid;
}
return lo < nums.length && nums[lo] === target ? lo : -1;
}
#StatusProblemTypeDifficultyDone
- 1#33 Search in Rotated Sorted ArrayGuidemedium
- 2#34 Find First and Last Position of Element in Sorted ArrayGuidemedium
- 3#35 Search Insert PositionGuideeasy
- 4#153 Find Minimum in Rotated Sorted ArrayGuidemedium
- 5#162 Find Peak ElementGuidemedium
- 6#704 Binary SearchGuideeasy