A complete visual walkthrough of binary search — finding a target or where it belongs in a sorted array.
The simplest approach: scan left to right until you find the target or the first element greater than the target. That index is your answer.
Array: [1, 3, 5, 6], target = 5
Array: [1, 3, 5, 6], target = 2
This works, but it's O(n) — we check every element in the worst case. Since the array is sorted, we can do much better.
// Brute force: O(n) for (int i = 0; i < nums.length; i++) { if (nums[i] >= target) return i; } return nums.length;
lo Is the AnswerStandard binary search narrows a range [lo, hi] until lo > hi. The beautiful insight for this problem:
When the loop ends without finding the target, lo always points to the correct insertion position. Here's why:
When lo crosses hi, lo sits right where the target would be inserted — all elements before lo are smaller, all elements from lo onward are larger.
This is the standard binary search template! The only difference from a "find element" binary search is: instead of returning -1 when not found, we return lo. That single change solves the entire problem.
Let's trace through with nums = [1, 3, 5, 6], target = 2 (insert case):
lo=0, hi=3, mid=1
nums[1] = 3 > target (2) → target is to the left → hi = mid - 1 = 0
lo=0, hi=0, mid=0
nums[0] = 1 < target (2) → target is to the right → lo = mid + 1 = 1
Return lo = 1 — insert 2 at index 1, between 1 and 3. The array becomes [1, 2, 3, 5, 6].
Binary search handles these naturally — no special code needed:
class Solution { public int searchInsert(int[] nums, int target) { int lo = 0, hi = nums.length - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; // avoids integer overflow if (nums[mid] == target) { return mid; // found it! } else if (nums[mid] < target) { lo = mid + 1; // search right half } else { hi = mid - 1; // search left half } } return lo; // not found — lo is the insert position } }
Why lo + (hi - lo) / 2 instead of (lo + hi) / 2? When lo and hi are both large, their sum can overflow a 32-bit integer. The subtraction form avoids this. Functionally identical, but safer.
Try different arrays and targets. Step through each binary search iteration to see lo, hi, and mid move.
Each iteration halves the search space. For an array of length n, we do at most log₂(n) iterations. We use only a few integer variables — no extra data structures.
Concrete numbers: For n = 1,000,000 elements, binary search takes at most 20 comparisons (since 2^20 ≈ 1M). The brute force would need up to 1,000,000 comparisons. That is the power of logarithmic time.