0
lo
A sorted array was rotated at some unknown pivot — binary search still works in O(log n) by comparing nums[mid] to nums[hi] (not nums[lo]) to reliably decide which half holds the minimum.
Given an array of distinct integers that was originally sorted in ascending order and then rotated at some unknown pivot, return the minimum element. You must run in O(log n).
Example: [4, 5, 6, 7, 0, 1, 2] was rotated from [0, 1, 2, 4, 5, 6, 7]. The answer is 0at index 4. A linear scan would work but costs O(n) — the O(log n) constraint forces binary search.
nums[mid] to nums[hi] tells you which half is normal: if nums[mid] > nums[hi], the left half is the larger segment and the minimum must be in the right half; otherwise the minimum is at mid or in the left half.nums[mid] to nums[lo]. This breaks on unrotated arrays (e.g. [1,2,3]) because nums[lo] is always ≤ nums[mid] in the unrotated left half, giving no information about which side to discard. Always anchor to nums[hi].lo = 0, hi = nums.length - 1. Loop while lo < hi.mid = ⌊(lo + hi) / 2⌋.nums[mid] > nums[hi], the minimum is strictly to the right of mid — set lo = mid + 1.nums[mid] ≤ nums[hi] means mid might be the minimum or the minimum is left — set hi = mid(include mid, don't skip it).lo === hi, both pointers sit on the minimum. Return nums[lo].Space is O(1) — only three integer pointers. No auxiliary structure needed.
lo=0, hi=6. We compare nums[mid] to nums[hi] (not nums[lo]) — this is the key insight.function findMin(nums: number[]): number {
let lo = 0;
let hi = nums.length - 1;
while (lo < hi) {
const mid = Math.floor((lo + hi) / 2);
if (nums[mid] > nums[hi]) {
// mid is in the left (larger) segment — min is to the right
lo = mid + 1;
} else {
// mid is in the right (smaller) segment — min is at mid or left
hi = mid;
}
}
return nums[lo]; // lo === hi — the minimum
}lo and hi bracket the entire array. The loop invariant is that the minimum always lives in [lo, hi] (inclusive).lo < hi. When the window collapses to one element (lo === hi), that element must be the minimum by the invariant — we exit and return it. Using < (not ≤) prevents an off-by-one infinite loop when lo === hi.nums[mid] > nums[hi], the rotation point lies to the right of mid, so the minimum is also to the right. We safely discard the left half by setting lo = mid + 1(mid itself is definitely not the minimum when it's greater than the rightmost element in range).nums[mid] ≤ nums[hi] means the right half is properly ordered and mid could be the minimum. We set hi = mid rather than hi = mid - 1 to preserve mid as a candidate. This is why the search terminates: mid = ⌊(lo+hi)/2⌋ < hi whenever lo < hi, so hi strictly decreases.lo === hi. By the invariant the minimum is in the window — and a window of size 1 has only one choice.lo, hi, and mid are tracked.nums[mid] === nums[hi]you can't tell which half is normal, so you must shrink with hi--. Worst case degrades to O(n).nums[mid] ≤ nums[hi] always, so hi walks left until lo === hi === 0.nums[lo]?” nums[lo] ≤ nums[mid] is always true in the unrotated left half, so it gives no signal about where the minimum is. The right boundary nums[hi] is the reliable anchor.| rotated sorted array, find minimum | binary search vs nums[hi] |
| nums[mid] > nums[hi] | lo = mid + 1 (min is right) |
| nums[mid] ≤ nums[hi] | hi = mid (mid may be the min) |
| sorted + partially broken invariant | binary search with right-boundary anchor |
function findMin(nums: number[]): number {
let lo = 0;
let hi = nums.length - 1;
while (lo < hi) {
const mid = Math.floor((lo + hi) / 2);
if (nums[mid] > nums[hi]) {
lo = mid + 1; // min is RIGHT of mid
} else {
hi = mid; // min is at mid or LEFT
}
}
return nums[lo];
}nums[lo] ≤ nums[mid] is always true in the unrotated left segment — it gives no information. nums[hi] reveals which half contains the rotation point.findMin?[4, 5, 6, 7, 0, 1, 2], what is the first value of mid and which pointer moves?nums[mid] ≤ nums[hi] you set hi = mid, not hi = mid - 1. Why?lo ≤ hi?[1, 2, 3, 4, 5] (no rotation), does the algorithm still return the correct answer?