We're given an array that was originally sorted in ascending order, then rotated some number of times. A rotation takes the last element and moves it to the front. After several rotations, the array has a specific structure: there's a "pivot point" where the values drop from a large number to a small number. Everything before the pivot is part of the larger segment, and everything from the pivot onward is the smaller segment.
For example, in [4, 5, 6, 7, 0, 1, 2], the pivot is at index 4 (value 0). The array has two sorted halves: [4, 5, 6, 7] and [0, 1, 2]. The minimum is always at the pivot point.
There's one special case: if the array is rotated n times (a full rotation), it's back to the original sorted order. In that case, there's no drop, and the minimum is the first element.
So the question boils down to: where is the pivot? The element at the pivot is smaller than its predecessor and is the global minimum.
1 <= n <= 5000 → With at most 5000 elements, even O(n) would be fast. But the problem explicitly requires O(log n), so we need binary search.nums is sorted and rotated between 1 and n times → Rotating n times gives back the original sorted array. So we need to handle the "not actually rotated" case too.Walk through the array and track the smallest element seen so far. This ignores the sorted-and-rotated structure, but it is correct and serves as a baseline before we optimize.
The minimum is either at the front (if the array completed a full rotation) or at the point where values drop. A linear scan finds it either way without reasoning about structure.
minimum to the first element of the array.minimum, update minimum.minimum.The linear scan works but ignores the sorted-and-rotated structure entirely. Since the array has two sorted halves, we can use binary search to eliminate half the search range at each step.
A rotated sorted array is made up of two sorted subarrays, with the minimum at the boundary between them. The larger subarray comes first, followed by the smaller one. If we can decide which half holds the minimum, we discard the other half and cut the search space in half each step. That is binary search.
To decide which half to keep, compare nums[mid] with nums[right]:
nums[mid] > nums[right], the minimum is somewhere after mid. The values rise from mid and then drop before reaching right, and that drop is where the minimum sits.nums[mid] <= nums[right], the minimum is at mid or to its left. The subarray from mid to right is sorted and increasing, so the minimum is not inside it, unless it is mid itself.Narrow the range until left == right. At that point nums[left] is the minimum.
Comparing with nums[right] rather than nums[left] is what makes the decision unambiguous. Take [3, 4, 5, 1, 2] with mid = 2 (value 5). Against nums[left] = 3, the result 5 > 3 only confirms the left portion is sorted, which says nothing about which side holds the minimum. Against nums[right] = 2, the result 5 > 2 shows the rotation point lies after mid.
The invariant is that the minimum always stays within [left, right]. When nums[mid] > nums[right], every element from left through mid belongs to the higher sorted segment, so the rotation point lies after mid. Setting left = mid + 1 excludes mid, which cannot be the minimum.
When nums[mid] <= nums[right], the subarray from mid to right is sorted and ascending. The minimum could be mid itself if mid is the rotation point, so right = mid keeps it in range. The loop ends when left == right, and since the minimum was never excluded, nums[left] is the answer. The range shrinks every iteration (left = mid + 1 strictly advances left, and right = mid strictly lowers right because mid < right whenever left < right), so termination is guaranteed.
left = 0 and right = nums.length - 1.left < right:mid = left + (right - left) / 2.nums[mid] > nums[right], the minimum is in the right half: set left = mid + 1.mid or in the left half: set right = mid.nums[left].