31. Find Minimum in Rotated Sorted Array
View on NeetCode
View on LeetCode
Problem
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:
[4,5,6,7,0,1,2]if it was rotated4times.[0,1,2,4,5,6,7]if it was rotated7times.
Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]].
Given the sorted rotated array nums of unique elements, return the minimum element of this array.
You must write an algorithm that runs in O(log n) time.
Example 1:
Input: nums = [3,4,5,1,2]
Output: 1
Explanation: The original array was [1,2,3,4,5] rotated 3 times.
Example 2:
Input: nums = [4,5,6,7,0,1,2]
Output: 0
Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
Example 3:
Input: nums = [11,13,15,17]
Output: 11
Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
Constraints:
n == nums.length1 <= n <= 5000-5000 <= nums[i] <= 5000- All the integers of
numsare unique. numsis sorted and rotated between1andntimes.
Solution
Approach: Modified Binary Search
The key insight is that the minimum element is at the “rotation point” where a larger element is followed by a smaller element. We can use binary search by comparing the middle element with the rightmost element to determine which half contains the minimum.
Logic:
- If
nums[mid] > nums[right], the minimum is in the right half (rotation point is to the right) - If
nums[mid] <= nums[right], the minimum is in the left half (including mid)
Implementation
class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
# If mid element is greater than right, minimum is in right half
if nums[mid] > nums[right]:
left = mid + 1
else:
# Minimum is in left half (including mid)
right = mid
return nums[left]
Alternative (Comparing with Left):
class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
result = nums[0]
while left <= right:
# If current subarray is already sorted
if nums[left] < nums[right]:
result = min(result, nums[left])
break
mid = (left + right) // 2
result = min(result, nums[mid])
# Determine which half to search
if nums[mid] >= nums[left]:
# Left half is sorted, search right
left = mid + 1
else:
# Right half is sorted, search left
right = mid - 1
return result
Complexity Analysis
- Time Complexity: O(log n), where n is the length of the array. We halve the search space with each iteration.
- Space Complexity: O(1), we only use a constant amount of extra space.
Key Insights
-
Rotation Point: The minimum element is at the rotation point, where the array “breaks” from its sorted order. Before the rotation point, elements are from the second part of the original array; after it, elements are from the first part.
-
Binary Search Modification: We compare
nums[mid]withnums[right](notnums[left]) to determine which half is sorted and which contains the rotation point. -
Sorted Subarray Check: If the entire current subarray is sorted (
nums[left] < nums[right]), thennums[left]is the minimum in that range. - Why Compare with Right: Comparing with the right element gives us a clear decision:
nums[mid] > nums[right]→ rotation point is to the rightnums[mid] <= nums[right]→ rotation point is to the left (or mid is minimum)
- No Duplicates: This problem assumes all elements are unique. With duplicates, we’d need to handle the case where
nums[mid] == nums[right]by linearly searching.