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 rotated 4
times.[0,1,2,4,5,6,7]
if it was rotated 7
times.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.
The most straightforward approach is to iterate through the entire array and find the minimum element. This involves comparing each element with the current minimum and updating the minimum if a smaller element is found.
def find_min_brute_force(nums):
min_val = nums[0]
for i in range(1, len(nums)):
if nums[i] < min_val:
min_val = nums[i]
return min_val
O(n), where n is the number of elements in the array, as we need to iterate through each element once.
O(1), as we only use a constant amount of extra space to store the minimum value.
Since the array is sorted and rotated, we can use binary search to find the minimum element in O(log n) time. The key idea is to compare the middle element with the elements at the left and right boundaries. If the middle element is greater than the rightmost element, then the minimum element must be in the right half. Otherwise, the minimum element must be in the left half (including the middle element).
left = 0
and right = len(nums) - 1
.left < right
:
mid = left + (right - left) // 2
to prevent overflow.nums[mid] > nums[right]
, then left = mid + 1
.right = mid
.nums[left]
(or nums[right]
, as they are the same at this point).def find_min(nums):
left = 0
right = len(nums) - 1
while left < right:
mid = left + (right - left) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
return nums[left]
O(log n), where n is the number of elements in the array, due to the binary search approach.
O(1), as we only use a constant amount of extra space.
1 <= n <= 5000
, which means the array will not be empty. However, in a real-world scenario, it's good practice to handle this edge case by adding a check at the beginning of the function.nums
are unique. If duplicate values were allowed, the binary search approach would need to be modified to handle cases where nums[mid] == nums[right]
. We could resolve this by simply decrementing the right pointer until nums[mid] != nums[right]
.The optimal solution using binary search provides a significant improvement in time complexity compared to the brute-force approach, making it more efficient for large arrays.