Find Minimum in Rotated Sorted Array
Find Minimum in Rotated Sorted Array:
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.
Try this Problem on your own or check similar problems:
Solution:
- Java
- JavaScript
- Python
- C++
public int findMin(int[] nums) {
int start = 0, end = nums.length-1;
while(start < end){
int mid = start + (end - start) / 2;
if(nums[end] < nums[mid]){
start = mid + 1;
}else{
end = mid;
}
}
return nums[start];
}
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function (nums) {
let start = 0;
let end = nums.length - 1;
while (start < end) {
let mid = Math.floor(start + (end - start) / 2);
if (nums[end] < nums[mid]) {
start = mid + 1;
} else {
end = mid;
}
}
return nums[start];
};
class Solution:
def findMin(self, nums: List[int]) -> int:
start = 0
end = len(nums) - 1
while start < end:
mid = start + (end - start) // 2
if nums[end] < nums[mid]:
start = mid + 1
else:
end = mid
return nums[start]
class Solution {
public:
int findMin(vector<int>& nums) {
int start = 0;
int end = nums.size() - 1;
while (start < end) {
int mid = start + (end - start) / 2;
if (nums[end] < nums[mid]) {
start = mid + 1;
} else {
end = mid;
}
}
return nums[start];
}
};
Time/Space Complexity:
- Time Complexity: O(logn)
- Space Complexity: O(1)
Explanation:
Modified binary search and the best way to explain it might be with examples:
[2, 3, 4, 5, 1]we havemidelement larger thanstartin that case we know left side is totally ordered and we check if element atmidis smaller than element atend, if it is we can discard the right side and only search in left side, if it's not it means that we have to search the right side[5, 1, 2, 3, 4]in this example by checking ifnums[mid] > nums[start]we get2 < 5so we know the right side is still in total order and we can check if the element atendis larger than element atminin non-rotated part, if it is that we know smallest number is either at mid or in the left side. If element atmidwas larger than the element atendwe would discard the element atmidat search the right sidestart = mid+1
- Java
- JavaScript
- Python
- C++
public int findMin(int[] nums) {
int start = 0, end = nums.length-1;
while(start < end){
int mid = start + (end - start) / 2;
if(nums[mid] > nums[start]){
if(nums[end] > nums[mid]){
end = mid - 1;
}else{
start = mid + 1;
}
}else{
if(nums[end] > nums[mid]){
end = mid;
}else{
start = mid + 1;
}
}
}
return nums[start];
}
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function (nums) {
let start = 0;
let end = nums.length - 1;
while (start < end) {
let mid = start + Math.floor((end - start) / 2);
if (nums[mid] > nums[start]) {
if (nums[end] > nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
} else {
if (nums[end] > nums[mid]) {
end = mid;
} else {
start = mid + 1;
}
}
}
return nums[start];
};
class Solution:
def findMin(self, nums: List[int]) -> int:
start = 0
end = len(nums) - 1
while start < end:
mid = start + (end - start) // 2
if nums[mid] > nums[start]:
if nums[end] > nums[mid]:
end = mid - 1
else:
start = mid + 1
else:
if nums[end] > nums[mid]:
end = mid
else:
start = mid + 1
return nums[start]
class Solution {
public:
int findMin(vector<int>& nums) {
int start = 0;
int end = nums.size() - 1;
while (start < end) {
int mid = start + (end - start) / 2;
if (nums[mid] > nums[start]) {
if (nums[end] > nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
} else {
if (nums[end] > nums[mid]) {
end = mid;
} else {
start = mid + 1;
}
}
}
return nums[start];
}
};
Now note that some scenarios aren't possible since the array was initially sorted, if we have:
nums[end] < nums[mid]that means that right side is not totally ordered and in the right side we will find our minimum numbernums[end] > nums[mid]which also impliesnums[mid] < nums[start]our right side is totally ordered, and the solution is either the element atmidor some element in the left side.
Using the above two points we can simplify the solution to:
- Java
- JavaScript
- Python
- C++
public int findMin(int[] nums) {
int start = 0, end = nums.length-1;
while(start < end){
int mid = start + (end - start) / 2;
if(nums[end] < nums[mid]){
start = mid + 1;
}else{
end = mid;
}
}
return nums[start];
}
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function (nums) {
let start = 0;
let end = nums.length - 1;
while (start < end) {
let mid = Math.floor(start + (end - start) / 2);
if (nums[end] < nums[mid]) {
start = mid + 1;
} else {
end = mid;
}
}
return nums[start];
};
class Solution:
def findMin(self, nums: List[int]) -> int:
start = 0
end = len(nums) - 1
while start < end:
mid = start + (end - start) // 2
if nums[end] < nums[mid]:
start = mid + 1
else:
end = mid
return nums[start]
class Solution {
public:
int findMin(vector<int>& nums) {
int start = 0;
int end = nums.size() - 1;
while (start < end) {
int mid = start + (end - start) / 2;
if (nums[end] < nums[mid]) {
start = mid + 1;
} else {
end = mid;
}
}
return nums[start];
}
};