public int search(int[] nums, int target) { int l = 0; int r = nums.length - 1; while (l <= r) { // [l, r] inclusive int m = l + (r - l) / 2; // no overflow if (nums[m] > target) { r = m - 1; } else if (nums[m] < target) { l = m + 1; } else { return m; } } return -1;}
- l
- —
- r
- —
- m
- —
- nums[m]
- —
- r − l + 1
- —
Why it works
- A linear scan ignores the sort: O(n). One look at the middle tells you which half cannot hold the target, so every probe halves the range: at most ⌈log₂(n+1)⌉ probes, 5 for 16 values, 30 for a billion.
- Invariant: if
targetis anywhere, it is inside[l, r]. It starts as the whole array, and each move throws away only cells that are proven wrong. - Why
l <= r: both ends are inclusive, sol == ris still one unchecked cell. Withl < r,[5]with target 5 returns -1. Whym ± 1:nums[m]is already ruled out. Writingr = mkeeps it, and oncel == r == mthe loop never ends. - Why
l + (r - l) / 2: it equals(l + r) / 2, butl + rcan overflow a 32-bitintand go negative once the array has over a billion cells.l + (r - l) / 2never leaves the range[l, r]. - O(log n) time, O(1) space. On a miss the loop ends with
l = r + 1, andlis exactly wheretargetwould be inserted: returnlinstead of -1 and you have 35 Search Insert Position.