Binary Search Mastery
Binary search is deceptively simple: find an element in a sorted array in O(log n). Yet it's one of the most bug-prone algorithms - studies show that 90% of programmers cannot write a correct binary search on their first attempt. This article covers the classic algorithm, its variants, and advanced applications like "binary search on the answer" that appear frequently in interviews and production systems.
๐ At a Glance
| Variant | Purpose | Returns |
|---|---|---|
| Classic | Find exact element | Index or -1 |
| Lower bound | First element โฅ target | Insertion point |
| Upper bound | First element > target | Insertion point |
| Equal range | Range of equal elements | [lower, upper) |
| Binary search on answer | Find minimum/maximum satisfying condition | Optimal value |
๐ฏ What You'll Learn
After reading this article, you will be able to:
- Write bug-free binary search every time using a systematic approach
- Choose the right variant (lower bound, upper bound, equal range)
- Apply binary search to non-array problems (parametric search)
- Handle edge cases including duplicates, rotated arrays, and 2D matrices
- Avoid classic bugs like integer overflow and off-by-one errors
- Recognize binary search opportunities in interview problems
๐ฅ Production Story: The Midnight Pricing Bug
An e-commerce platform used binary search to find applicable price tiers based on order quantity. During a flash sale, customers reported being charged incorrect prices.
JAVA(27 lines)CodeLoading syntax highlighter...
- Order of 100 units returned tier 1 ($8) but should return tier 1 - correct by accident
- Order of 99 units returned tier 1 ($8) instead of tier 0 ($10)!
- Order of 500 units sometimes returned tier 1 instead of tier 2
JAVA(36 lines)CodeLoading syntax highlighter...
๐ง Mental Model: The Binary Search Family
TEXT(44 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: Classic Binary Search
๐ฎ Try It Yourself
Watch binary search divide the search space in half with each step. Enter a target value and observe how left, mid, and right pointers converge:
Loading visualizer...
The Correct Implementation
JAVA(26 lines)CodeLoading syntax highlighter...
Why lo + (hi - lo) / 2?
JAVA(15 lines)CodeLoading syntax highlighter...
Loop Invariant Analysis
TEXT(29 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: Lower Bound and Upper Bound
Lower Bound (bisect_left)
JAVA(26 lines)CodeLoading syntax highlighter...
Upper Bound (bisect_right)
JAVA(26 lines)CodeLoading syntax highlighter...
Equal Range
JAVA(27 lines)CodeLoading syntax highlighter...
Comparison of Variants
| Variant | Condition | When lo moves | When hi moves | Returns |
|---|---|---|---|---|
| Exact | arr[mid] == target | arr[mid] < target | arr[mid] > target | Found index or -1 |
| Lower bound | arr[mid] >= target | arr[mid] < target | arr[mid] >= target | First โฅ target |
| Upper bound | arr[mid] > target | arr[mid] <= target | arr[mid] > target | First > target |
๐ฌ Deep Dive: Binary Search on Answer
The Paradigm
Binary search isn't just for finding elements in arrays. It can solve any problem where:
- The answer space is ordered (monotonic)
- You can verify if a candidate answer is valid in reasonable time
TEXT(15 lines)CodeLoading syntax highlighter...
Example: Minimum Ship Capacity
JAVA(49 lines)CodeLoading syntax highlighter...
Example: Koko Eating Bananas
JAVA(32 lines)CodeLoading syntax highlighter...
Example: Split Array Largest Sum
JAVA(42 lines)CodeLoading syntax highlighter...
Recognizing Binary Search on Answer Problems
| Pattern | Example Problem |
|---|---|
| "Minimize the maximum..." | Split array largest sum |
| "Maximize the minimum..." | Magnetic force between balls |
| "Find minimum X such that..." | Ship capacity, eating speed |
| "Find maximum X such that..." | Maximum candies allocated |
| Monotonic feasibility | If X works, X+1 also works (or vice versa) |
๐ฌ Deep Dive: Rotated Sorted Array
Finding Element in Rotated Array
JAVA(37 lines)CodeLoading syntax highlighter...
Finding Minimum in Rotated Array
JAVA(27 lines)CodeLoading syntax highlighter...
Handling Duplicates
JAVA(42 lines)CodeLoading syntax highlighter...
๐ฌ Deep Dive: 2D Matrix Search
Row-Column Sorted Matrix
JAVA(35 lines)CodeLoading syntax highlighter...
Fully Sorted Matrix
JAVA(39 lines)CodeLoading syntax highlighter...
โ ๏ธ Common Mistakes
Mistake 1: Integer Overflow in Mid Calculation
JAVA(6 lines)CodeLoading syntax highlighter...
Mistake 2: Wrong Loop Condition
JAVA(11 lines)CodeLoading syntax highlighter...
Mistake 3: Off-by-One in Bound Updates
JAVA(11 lines)CodeLoading syntax highlighter...
Mistake 4: Wrong Condition in Bounds Search
JAVA(9 lines)CodeLoading syntax highlighter...
Mistake 5: Not Handling Empty Array
JAVA(12 lines)CodeLoading syntax highlighter...
๐ Debug This: The Buggy Binary Search Collection
These binary search implementations have bugs. Find and fix them:
JAVA(53 lines)CodeLoading syntax highlighter...
๐ก Hint
Look for:
- Inclusive vs exclusive bounds consistency
- Infinite loop conditions
- Off-by-one errors in first occurrence
- Integer overflow in multiplication
- Returning lo vs lo-1
โ Solution
JAVA(60 lines)CodeLoading syntax highlighter...
-
search(): Using
hi = lengthwithwhile (lo < hi)but treating it as exact search. Alsolo = midcauses infinite loop. Mixed paradigms. -
firstOccurrence(): Using
while (lo <= hi)withhi = midcauses infinite loop whenlo == hi == midandarr[mid] == target. -
sqrt():
mid * midoverflows for large x. Also, the logic for finding floor(sqrt) was inverted.
๐ป Exercises
Exercise 1: Find Peak Element โญ
arr[i] โ arr[i+1]. A peak is greater than neighbors.JAVA(11 lines)CodeLoading syntax highlighter...
๐ก Hint
If arr[mid] < arr[mid+1], a peak must exist to the right. Otherwise, a peak exists to the left (or at mid).
Exercise 2: Search in 2D Matrix (Arbitrary Sorted) โญโญ
Matrix where rows are sorted left-to-right, columns are sorted top-to-bottom (but row end may be less than next row start).
JAVA(8 lines)CodeLoading syntax highlighter...
Exercise 3: Find Minimum in Rotated Array II โญโญโญ
Find minimum in rotated sorted array that may contain duplicates.
JAVA(8 lines)CodeLoading syntax highlighter...
Exercise 4: Aggressive Cows (Binary Search on Answer) โญโญโญ
Place C cows in N stalls at positions xโ, xโ, ..., xโ. Maximize minimum distance between any two cows.
JAVA(10 lines)CodeLoading syntax highlighter...
๐ก Hint
Binary search on the answer (minimum distance). For each candidate distance D, check if you can place all cows with at least D distance apart using greedy placement.
Exercise 5: Median of Two Sorted Arrays โญโญโญโญ
Find median of two sorted arrays in O(log(min(m,n))) time.
JAVA(9 lines)CodeLoading syntax highlighter...
๐ก Hint
Binary search on partition point of smaller array. If we partition both arrays such that left halves have (m+n+1)/2 elements total, median is derived from elements around partition.
๐ค Interview Questions
Question 1: Why is binary search often implemented incorrectly?
Binary search is tricky because of several interdependent decisions:
-
Bounds: inclusive vs exclusive?
hi = arr.length - 1(inclusive) vshi = arr.length(exclusive)- Must be consistent throughout
-
Loop condition: < or <=?
while (lo < hi)for bounds search (hi = length)while (lo <= hi)for exact search (hi = length - 1)
-
Update rules: mid or midยฑ1?
- Must ensure progress (no infinite loops)
- Must not skip potential answers
-
Different variants need different logic
- Exact search, lower bound, upper bound all differ
Question 2: When would you use binary search over hash table lookup?
Use binary search when:
-
Memory constrained: Binary search is O(1) space, hash table is O(n)
-
Range queries needed: "Find all elements between A and B" - binary search gives O(log n + k), hash table is O(n)
-
Ordered iteration needed: Binary search maintains order, hash tables don't
-
Predecessor/successor queries: "Find largest element โค X" - O(log n) with binary search, O(n) with hash table
-
Data is already sorted: No preprocessing needed
Use hash table when:
- Exact lookup only: O(1) average vs O(log n)
- Frequent insertions/deletions: Hash table is O(1), maintaining sorted array is O(n)
- Memory is plentiful: Hash table's O(1) lookup is hard to beat
Question 3: Explain binary search on answer with an example
Binary search on answer finds optimal value when:
- Answer space is ordered
- There's a monotonic feasibility function
Problem: N books with pages[i]. Allocate to K students such that maximum pages assigned to any student is minimized. Each student gets contiguous books.
JAVA(30 lines)CodeLoading syntax highlighter...
The key insight: if we can allocate with max=X, we can also allocate with max=X+1. This monotonicity enables binary search.
Question 4: How would you handle duplicates in binary search?
Duplicates affect what "find" means:
-
Find any occurrence: Standard binary search works (returns any matching index)
-
Find first occurrence (lower bound):
JAVA(5 lines)CodeLoading syntax highlighter...
- Find last occurrence:
JAVA(5 lines)CodeLoading syntax highlighter...
-
Count occurrences:
upperBound - lowerBound -
Rotated array with duplicates: Worst case becomes O(n) because can't determine which half is sorted when
arr[lo] == arr[mid] == arr[hi].
Question 5: Compare iterative vs recursive binary search
| Aspect | Iterative | Recursive |
|---|---|---|
| Space | O(1) | O(log n) stack |
| Performance | Slightly faster (no call overhead) | Slightly slower |
| Readability | More explicit | More elegant |
| Tail recursion | N/A | Could be optimized (not in Java) |
| Debugging | Easier (can inspect lo, hi) | Harder (stack frames) |
JAVA(21 lines)CodeLoading syntax highlighter...
๐ Quick Reference
Binary Search Templates
JAVA(8 lines)CodeLoading syntax highlighter...
JAVA(7 lines)CodeLoading syntax highlighter...
JAVA(7 lines)CodeLoading syntax highlighter...
JAVA(7 lines)CodeLoading syntax highlighter...
Common Patterns
| Pattern | Recognize By | Template |
|---|---|---|
| Find element | "Find X in sorted array" | Exact search |
| Find position | "Where would X be inserted?" | Lower/upper bound |
| Find first/last | "First occurrence of X" | Modified bounds |
| Find optimal | "Minimum capacity such that..." | Search on answer |
| Rotated array | "Sorted then rotated" | Two-phase analysis |
Java Standard Library
JAVA(15 lines)CodeLoading syntax highlighter...
๐ Review Schedule
| Day | Focus | Time |
|---|---|---|
| Day 1 | Read full article, understand all templates | 60 min |
| Day 3 | Implement exact, lower bound, upper bound from scratch | 30 min |
| Day 7 | Solve 3 "binary search on answer" problems | 45 min |
| Day 14 | Solve rotated array variants | 30 min |
| Day 30 | Mock interview: explain and implement | 20 min |
๐ What's Next?
- Ternary search for unimodal functions
- Interpolation search for uniform distributions
- Exponential search for unbounded arrays
- Fibonacci search
- Jump search