Find Minimum in Rotated Sorted Array
Find Minimum in Rotated Sorted Array is LeetCode 153, and it is one of those problems that teaches you binary search is about more than just "find a target." There is no target here. You are looking for the inflection point, the spot where the array wraps around. And you can find it in O(log n) using the same binary search pivot logic you already know.
If you have solved Search in Rotated Sorted Array (LeetCode 33), this is actually the simpler version. Instead of searching for a specific value in a rotated array, you are just finding where the rotation happened. That rotation point is the minimum.
The problem
You are given a sorted array of unique integers that has been rotated between 1 and n times. Find the minimum element. You must solve it in O(log n) time.
Example: nums = [3, 4, 5, 1, 2]. The original sorted array was [1, 2, 3, 4, 5], and it was rotated 3 times. The minimum is 1.
The minimum always sits at the binary search pivot, the exact point where the sorted order breaks. On the left side of the pivot, values are larger. On the right side, values restart from the smallest. Finding that pivot is the whole problem.
Why you cannot just scan
Sure, you could loop through the array in O(n) and track the smallest value. But the problem requires O(log n). That means you need to cut the search space in half at each step. The array is almost sorted, which is a strong hint that binary search applies.
The question is: what condition do you use to decide which half to keep?
The key insight: compare mid to the right boundary
In a rotated sorted array, you can figure out which side the minimum is on by comparing nums[mid] to nums[hi].
- If
nums[mid]is greater thannums[hi], the rotation break is somewhere to the right of mid. The minimum must be in the range[mid + 1, hi]. - If
nums[mid]is less than or equal tonums[hi], the right half is sorted and has no break. The minimum is atmidor to the left:[lo, mid].
That is it. One comparison per step, and you throw out half the array.
The trick for find minimum in rotated sorted array: compare nums[mid] to nums[hi]. If mid is bigger, the break (and the minimum) is to the right. If mid is smaller or equal, mid itself might be the minimum, so keep it and search left.
Visual walkthrough
Let's find the minimum in [3, 4, 5, 1, 2] step by step using binary search on the pivot.
Step 1: lo=0, hi=4, mid=2. nums[2]=5. nums[mid] > nums[hi] (5 > 2), so the minimum is in the right half.
The right half contains the rotation break. Set lo = mid + 1 = 3.
Step 2: lo=3, hi=4, mid=3. nums[3]=1. nums[mid] < nums[hi] (1 < 2), so the minimum is at mid or to the left.
The right half is sorted, so mid could be the answer. Set hi = mid = 3.
Step 3: lo=3, hi=3. lo == hi. We found the minimum: nums[3] = 1.
The search space has collapsed to one element. Return nums[3] = 1.
Two real comparisons. Out of 5 elements, we found the minimum in O(log n) time. The search space shrinks by half at each step until only one element remains.
The code
Here is the complete Python solution for LeetCode 153, find minimum in rotated sorted array:
def find_min(nums):
lo, hi = 0, len(nums) - 1
while lo < hi:
mid = lo + (hi - lo) // 2
if nums[mid] > nums[hi]:
lo = mid + 1
else:
hi = mid
return nums[lo]
Let's break this down.
The loop condition is lo < hi, not lo <= hi. This is important. We are not looking for a target where we might return early. We are narrowing down to a single index. When lo == hi, we have found it.
mid = lo + (hi - lo) // 2 is the standard overflow-safe midpoint calculation, identical to the binary search template.
if nums[mid] > nums[hi] means the rotation break is to the right of mid. The minimum cannot be at mid (it is bigger than something to its right), so we safely set lo = mid + 1.
else: hi = mid means mid could be the minimum, or the minimum is to the left. We cannot skip mid, so we set hi = mid (not mid - 1).
A common mistake is writing hi = mid - 1 in the else branch. You cannot do that because mid itself might be the minimum. If you skip it, you miss the answer. Always use hi = mid when the current element is still a candidate.
Why compare to nums[hi] and not nums[lo]?
This trips people up. Why not compare nums[mid] to nums[lo] like you do in Search in Rotated Sorted Array?
Consider the array [1, 2, 3, 4, 5] (not rotated at all). If you check nums[mid] > nums[lo], that is 3 > 1, which is true. You would set lo = mid + 1 and skip right past the actual minimum at index 0.
Comparing to nums[hi] avoids this. nums[mid] > nums[hi] is 3 > 5, which is false. You correctly keep the left half and converge on the minimum.
The nums[hi] comparison works in all cases: rotated arrays, and arrays that were not rotated at all.
Complexity analysis
Time: O(log n). Each step eliminates half the search space. The loop runs at most log2(n) times.
Space: O(1). Three variables: lo, hi, mid. No extra data structures.
This matches the problem's requirement and is optimal. You cannot locate the pivot in fewer than O(log n) comparisons.
Edge cases to watch for
- Not rotated:
nums = [1, 2, 3, 4, 5]. The minimum is at index 0.nums[mid]is never greater thannums[hi], sohikeeps moving left untillo == hi == 0. Works correctly. - Single element:
nums = [1].lo == hifrom the start, so the loop never runs. We returnnums[0]. - Two elements:
nums = [2, 1].mid = 0,nums[0] = 2 > nums[1] = 1, solo = 1. Nowlo == hi, returnnums[1] = 1. - Rotated by one:
nums = [5, 1, 2, 3, 4]. The minimum is at index 1. The first comparison seesnums[2] = 2which is less thannums[4] = 4, sohi = 2. Thennums[1] = 1which is less thannums[2] = 2, sohi = 1. Thenlo == hi == 1. Correct.
The building blocks
This problem is built on one core building block: binary-search-template.
The skeleton is exactly the standard binary search: maintain [lo, hi], compute mid, eliminate half the range. The only thing that changes is the decision logic. Instead of comparing nums[mid] to a target, you compare nums[mid] to nums[hi] to decide which half contains the rotation break.
# Standard binary search (find target):
while lo <= hi:
mid = lo + (hi - lo) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
lo = mid + 1
else:
hi = mid - 1
# Find minimum in rotated array:
while lo < hi:
mid = lo + (hi - lo) // 2
if nums[mid] > nums[hi]:
lo = mid + 1
else:
hi = mid
Two small differences: the loop condition (< vs <=) and the comparison (nums[mid] vs target becomes nums[mid] vs nums[hi]). If you can write the binary search template from memory, this problem is just swapping out the comparison.
This "binary search on a property" pattern shows up in several related problems:
- Search in Rotated Sorted Array (LeetCode 33): search for a target in the same structure, using the sorted-half check
- Find Peak Element (LeetCode 162): binary search where you compare mid to its neighbor
- Find Minimum in Rotated Sorted Array II (LeetCode 154): same idea but with duplicates, worst case O(n)
From understanding to recall
The logic here is clean: compare mid to hi, go right if mid is bigger, shrink left otherwise. Simple enough to understand in one sitting.
But in an interview, when you are also thinking about edge cases and time pressure is mounting, the details slip. Was it lo < hi or lo <= hi? Do you set hi = mid or hi = mid - 1? Do you compare to nums[lo] or nums[hi]? These small choices are the difference between a correct solution and an infinite loop.
Spaced repetition solves this. You type the solution from scratch today, then again tomorrow, then in three days. By the fourth repetition, the while lo < hi and hi = mid are muscle memory. You are not deriving them from scratch under pressure. You just know.
LeetCode 153 is a perfect candidate for SRS drilling because the code is short but the decisions are subtle. Get it into long-term memory once, and every rotated-array variant becomes easier.
Related posts
- Search in Rotated Sorted Array (LeetCode 33): Modified Binary Search - Uses the same rotated structure but searches for a specific target instead of the minimum
- Binary Search (LeetCode 704): The Foundation - Master the standard binary search template first, then this pivot variant becomes a small modification on top