Find the Smallest Element After a Sorted Array Is Rotated
Solve this Problem[0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]. Given the rotated array nums, return its smallest element.
Solve it in O(log n) time by binary-searching for the "seam" where the array's values drop from high back down to low.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ nums.length ≤ 5000 - ◆
-5000 ≤ nums[i] ≤ 5000 - ◆
All the values of nums are unique - ◆
nums was sorted in ascending order, then possibly rotated
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public int findMin(int[] nums) { |
| 3 | int lo = 0, hi = nums.length - 1; |
| 4 | while (lo < hi) { |
| 5 | int mid = lo + (hi - lo) / 2; |
| 6 | if (nums[mid] > nums[hi]) { |
| 7 | lo = mid + 1; |
| 8 | } else { |
| 9 | hi = mid; |
| 10 | } |
| 11 | } |
| 12 | return nums[lo]; |
| 13 | } |
| 14 | } |
| 15 |
06Search [0, 6] for the seam where the rotation drops back down to the smallest value.
Approach & Solutions
Brute Force — Linear Scan
BruteTrack the smallest value seen so far while walking the whole array once. It works regardless of rotation, but it never uses the fact that a rotated sorted array is really just two sorted runs glued together, which is what lets binary search skip most of the array.
O(n)O(1)1class Solution {
2 public int findMin(int[] nums) {
3 int minIdx = 0;
4 for (int i = 1; i < nums.length; i++) {
5 if (nums[i] < nums[minIdx]) minIdx = i;
6 }
7 return nums[minIdx];
8 }
9}Optimal — Binary Search
OptimalThe minimum sits exactly at the "seam" where the rotation drops from a high value back down to a low one. Compare nums[mid] against nums[hi]: if nums[mid] > nums[hi], the seam (and the minimum) is somewhere to the right of mid, so search there. Otherwise the array from lo to mid is already the "reset" side, so the minimum is at mid or to its left — keep mid in range.
O(log n)O(1)1class Solution {
2 public int findMin(int[] nums) {
3 int lo = 0, hi = nums.length - 1;
4 while (lo < hi) {
5 int mid = lo + (hi - lo) / 2;
6 if (nums[mid] > nums[hi]) {
7 lo = mid + 1;
8 } else {
9 hi = mid;
10 }
11 }
12 return nums[lo];
13 }
14}