The 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 rotated4
times.[0,1,2,4,5,6,7]
if it was rotated7
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.
Examples
Input: nums = [3,4,5,1,2]
Output: 1
Explanation: The original array was [1,2,3,4,5] rotated 3 times.
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.
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.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
- All the integers of
nums
are unique. nums
is sorted and rotated between1
andn
times.
Brute Force Solution
func findMin(_ nums: [Int]) -> Int {
return nums.min()!
}
Explanation
The easiest way to solve this problem is to use Swift’s built-in min
function, but it takes O(n)
time. Underline, it just loops through the entire input and finds the minimum element.
The more optimal way to solve this problem is to use binary search.
Time/Space Complexity
- Time complexity:
O(n)
- Space complexity:
O(1)
Solution - 2 - Binary Search
func findMin(_ nums: [Int]) -> Int {
var res = nums[0]
var l = 0
var r = nums.count - 1
while l <= r {
if nums[l] < nums[r] {
res = min(res, nums[l])
break
}
let m = (l + r) / 2
res = min(res, nums[m])
if nums[m] >= nums[l] {
l = m + 1
} else {
r = m - 1
}
}
return res
}
Explanation
This solution uses a slightly modified binary search; the prerequisite for binary search is that to achieve O(log n)
time, you need sorted input.
In this solution, we use a slightly different approach. Since we are using a rotated array as input, we use the condition
nums[m] >= nums[l]
to look into the left or right side of the input nums
and update pointers. For example, if we have the rotated array [3, 4, 5, 1, 2]
, our middle
pointer will be 5
, and the left
pointer will be 3
. Following the condition nums[m] >= nums[l]
, we update the left
pointer. When that condition is not satisfied, for example, when the middle
pointer is at 5
and the left
pointer is at 1
, we update the right
pointer.
Time/Space Complexity
- Time complexity:
O(log n)
- Space complexity:
O(1)