Recognize the Pattern
- The array is sorted, and you need to find a value or where it would fit.
- You need the first or last matching position when values repeat.
- One comparison lets you rule out a whole half. Without that reason, binary search is not safe.
Core Invariant
If the target exists, it is still between left and right. Sorted order lets each comparison remove a half that cannot contain it.
Important Boundary
Start with sorted data. The basic version returns any matching index; finding the first match needs a different stopping rule.
Compare the middle and keep one half
Template Assumptions
- Numeric values sorted from smallest to largest, with array indices in the safe-integer range.
- Returns any matching index, or -1 if missing. Does not sort or mutate the array.
JavaScript Template
- left and right are the first and last positions still worth checking. Start with the whole array.
- If nums[mid] is the target, return mid. If it is smaller, every value to its left is also too small: move left to mid + 1.
- If nums[mid] is larger, every value to its right is also too large: move right to mid - 1.
- When left passes right, no positions remain. Return -1 because the target is missing.
Walk through finding 11
If the target were 8, the middle checks would be 7, 11, then 9. The last comparison moves right to 3 while left is 4. There is nothing left to check, so return -1.
| left, right | mid: value | Compare with 11 | Next action |
|---|---|---|---|
| 0,6 | 3: 7 | 7 is too small | left = 4; keep [9,11,13] |
| 4,6 | 5: 11 | 11 matches | return index 5 |
Step-by-Step: Binary search: keep the half containing 11
- Search bounds
- [0,6]
- Middle
- index 3: value 7
- Result
- not found yet
Check the middle: 7
left = 0 and right = 6 give mid = 3. The value 7 is smaller than 11. Every value at indices 0 through 3 is too small, so the next step moves left to 4.
When values repeat: find the first match
The basic code can return any matching position. For [1,3,3,7,9], it returns index 2 for target 3. If you need the first 3, do not stop at equality: keep looking left.
The version below finds the first position whose value is at least the target. This is called lower bound. For target 3 it returns 1; for target 4 it returns 3, where 4 would fit before 7.
Template Assumptions
- Numeric values sorted from smallest to largest; duplicates are allowed.
- Returns the first index with value >= target, or nums.length when all values are smaller. Empty input returns 0.
JavaScript Template
- Here right starts at nums.length and is outside the searchable range. Use left < right, not the basic version's left <= right.
- If nums[mid] is at least the target, keep mid as a possible answer with right = mid. Otherwise skip it with left = mid + 1.
- If every value is smaller, return nums.length: the target would fit after the array. To check whether it exists, require index < nums.length and nums[index] === target.
Other problems that use the same idea
- Rotated arrays: [5,7,9,1,3] is not sorted from end to end. With distinct values, identify which half is sorted before choosing where to search. Duplicates can make the worst case linear.
- Sorted matrices: treat rows as one long sorted array only if each row is sorted and its first value exceeds the previous row's last value. Sorted rows alone are not enough.
- Searching possible answers: suppose a package capacity of 10 is enough to finish within a fixed number of days. Any larger capacity must also be enough. You can search for the smallest working capacity because answers change once from 'not enough' to 'enough', never back again.
- Longest Increasing Subsequence uses binary search on a sorted helper array, not on the original input. Learn that problem's helper meaning separately; its values are not necessarily an actual subsequence.
Time, space, and practical limits
- Sorted-array search takes O(log N) time for nonempty input and O(1) extra space. Each check roughly halves the remaining positions. Empty input takes constant time and returns -1 in the basic version.
- If you sort first, include that cost: comparison sorting typically takes O(N log N) and changes positions. For one lookup in unsorted data, a linear scan may be simpler.
- Searching possible answers also pays for each test. If testing one capacity costs O(N), multiply that by the number of search steps.
- Use Math.floor for the midpoint, not a bitwise shortcut: JavaScript bitwise operators convert numbers to 32-bit integers. Keep numeric bounds and calculations within the safe-integer range.
Mistakes and Counterexamples
Keep a midpoint you already know is too small.
Counterexample: With left 0 and right 1, the midpoint is 0. If its value is too small, left = mid leaves the same range and can loop forever.
Correction: Use left = mid + 1 after a too-small value. Every iteration must remove a position or return the answer.
Mix the two versions' loop conditions and bounds.
Counterexample: For one value [3], the basic search needs left <= right to check index 0. The lower-bound version starts right at length and must not read that outside position.
Correction: Keep each version's initialization, loop condition, and updates together. Check a lower-bound result against length before reading it.
Last-Minute Recap
- Check the middle and explain why one half cannot contain the answer.
- Too small: move left past mid. Too large: move right before mid.
- Finding any match and finding the first match need different stopping rules.
- Include sorting and the cost of checking a possible answer.
Explain It in an Interview
- Why can you skip every value to the left when the middle is too small?
- What happens with an empty array, one value, or a missing target?
- How would you keep searching when you need the first of several equal values?
Ready to Apply This Pattern?
Before coding, explain why this pattern fits and what must stay true at each step. Start with an easier problem, then test that reasoning on a harder variation.
Ordered from Easy to Hard. Premium access requirements still apply.
- 1.Binary Search - Efficient SearchCompare the middle value, discard the correct half, and return -1 when the target is absent.Easy
- 2.Search in Rotated Sorted ArrayFind the sorted half before deciding which positions can safely be skipped.Medium
- 3.Search a 2D MatrixCheck that rows form one globally sorted sequence before mapping a flat index to a cell.Medium
- 4.Longest Increasing SubsequenceSearch a sorted helper array and explain why equal values do not extend a strictly increasing sequence.Medium
- 5.Median of Two Sorted ArraysSearch a partition in the shorter array and enforce cross-partition ordering at empty boundaries.Hard
- 6.Path With Maximum Minimum ValueBinary-search a score threshold using monotone graph reachability as the feasibility test.Hard