153. Find Minimum in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
Find the minimum element.
You may assume no duplicate exists in the array.
Example 1:
Input: [3,4,5,1,2]
Output: 1
Example 2:
Input: [4,5,6,7,0,1,2]
Output: 0
方法1: binary search
思路:
我们的目标是找到一个nums[mid - 1] > nums[mid],为了不越界,从left = 1开始遍历。采用left<right的终止条件。当出现满足条件的值,直接返回nums[mid],否则,需要判断需要往那边走。我们通过判断nums[mid] 和nums[right],注意这里不用left和mid判断大小,因为在edge case的时候left == mid,没有任何信息量来判断应该往左还是往右。最后,出循环的时候一定是因为left== right。此时如果当前点left并不符合条件,那么一定是因为整个序列都是递增,那么此时剩下的一个nums[0]如果比left大,left为最小,如果比left小,nums[0]为结果。简而言之,left和nums[0]较小为结果。
Complexity
Time complexity: O(log n)
Space complexity: O(1)
class Solution {
public:
int findMin(vector<int>& nums) {
int n = nums.size();
if (n == 1) return nums[0];
int left = 1, right = n - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid - 1] > nums[mid]) return nums[mid];
else {
if (nums[mid] <= nums[right]) right = mid;
else left = mid + 1;
}
}
if (nums[left - 1] > nums[left]) return nums[left];
return nums[0];
}
};
另一种写法:
class Solution1 {
public:
int findMin(vector<int>& nums) {
if (nums.size() == 0) return NULL;
if (nums.size() == 1) return nums[0];
int left = 1;
int right = nums.size() - 1;
while (left <= right){
int mid = left + (right - left) / 2;
if (nums[mid - 1] > nums[mid]) return nums[mid];
if (nums[mid] <= nums[right]){
right = mid - 1;
}
else{
left = mid + 1;
}
}
return min(nums[left-1], nums[left]);
}
};
方法2: recursion
思路:
//分治
class Solution2 {
public:
int findMin(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
return findHelper(nums, left, right);
}
int findHelper(vector<int> &nums, int left, int right){
// 没有下面这个if语句会死循环
// 无法解决left = mid < right, length = 2 的情况
if (left >= right - 1) return min(nums[left], nums[right]);
int mid = left + (right - left) / 2;
if (nums[left] < nums[right]){
return nums[left];
}
else if (nums[mid] <= nums[right]){
return min(nums[mid], findHelper(nums, left, mid - 1));
}
else return min(nums[left], findHelper(nums, mid, right));
}
};