Problem statement :
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.
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.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
All the integers of
nums
are unique.nums
is sorted and rotated between1
andn
times.Here is the solution :
var findMin = function(nums) { let low = 0; let n = nums.length; let high = n-1; while (low < high) { let mid = Math.floor((low + high) / 2); if (nums[mid] > nums[high]) { low = mid + 1; } else { high = mid; } } return nums[low]; };
The core idea of this approach is to divide the search space in half at each step by comparing the middle element with the rightmost element.
Let's illustrate this with an example: nums = [3, 4, 5, 1, 2]
.
low
starts at 0, andhigh
starts at 4 (length ofnums
- 1).In the first iteration,
mid
becomes 2, and we comparenums[2]
(5) withnums[4]
(2).Since
nums[mid] > nums[high]
, we updatelow
tomid + 1
, making it 3.The next iteration sets
mid
to 3, and we comparenums[3]
(1) withnums[4]
(2).Now,
nums[mid] < nums[high]
, so we updatehigh
tomid
, making it 3.
Finally, when low
and high
converge, we find that the minimum element is at nums[low]
, which is 1.
Alternative Solution: Binary Search Approach (Recursive):
In this section, we'll explore an alternative solution using a recursive binary search approach. Here's the code:
function findMin(nums, low = 0, high = nums.length - 1) {
if (low === high) {
return nums[low];
}
let mid = Math.floor((low + high) / 2);
if (nums[mid] > nums[high]) {
return findMin(nums, mid + 1, high);
} else {
return findMin(nums, low, mid);
}
}
This alternative approach follows a similar logic to the first solution but uses recursion to simplify the code.
Comparing the Two Solutions:
Both solutions follow the binary search approach, achieving the required O(log n) time complexity. The choice between the two largely depends on your coding style and preferences. Solution 1 is iterative, while the alternative (Solution 2) is recursive.
Quiz :
What is the time complexity of the binary search algorithm used in these solutions?
a) O(n)
b) O(log n)
c) O(n log n)
d) O(1)
Additional Resources: