問題描述(153):
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
源碼(153):
其實就是二分查找,但是一定要注意的就是R和L的處理,我們是把R=mid而L=mid+1。因爲當nums[i]<nums[R]的時候,mid處有可能是最小值,而反之L處不可能是最小值,所以等於mid+1。
class Solution {
public:
int findMin(vector<int>& nums) {
int L=0, R=nums.size()-1, mid=0;
while(L<R){
mid = (R+L)/2;
if(nums[mid]<nums[R]) R = mid;
else L = mid+1;
}
return nums[L];
}
};
如果硬要全部都是Mid的話,要考慮L可能永遠不等於R,此時加一句判斷,R-L==1。
也不知道爲啥空間這麼低,最近leetcode的空間一直都不高,前陣子一直都是100%時間不行,迷得不行。
class Solution {
public:
int findMin(vector<int>& nums) {
int L=0, R=nums.size()-1, mid=0;
while(L<R){
if(R-L==1) return min(nums[R], nums[L]);
mid = (R+L)/2;
if(nums[mid]<nums[R]) R = mid;
else L = mid;
}
return nums[L];
}
};
問題描述(154):
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.
The array may contain duplicates.
Example 1:
Input: [1,3,5] Output: 1
Example 2:
Input: [2,2,2,0,1] Output: 0
Note:
- This is a follow up problem to Find Minimum in Rotated Sorted Array.
- Would allow duplicates affect the run-time complexity? How and why?
源碼(154):
這題和《劍指offer》第二版面試題11是一樣的,我先展示一下書上的做法,當發現左右和中間的元素相等的時候,就需要線性遍歷了。
class Solution {
public:
int find(vector<int>& nums, int L, int R){
int result = nums[L];
for(int i=L+1; i<=R; i++){
result = min(result, nums[i]);
}
return result;
}
int findMin(vector<int>& nums) {
int L=0, R=nums.size()-1, mid=0;
if(R==0) return nums[R];
while(nums[L] >= nums[R]){
if(R-L == 1) return nums[R];
mid = (L+R)/2;
if(nums[mid]==nums[L] && nums[mid]==nums[R]) return find(nums, L, R);
if(nums[mid] >= nums[L]) L = mid;
else if(nums[mid] <= nums[R]) R = mid;
}
return nums[mid];
}
};
自己調了半天的寫法,很挫,就是不想直接順序遍歷下去。
class Solution {
public:
int findMin(vector<int>& nums) {
int L=0, R=nums.size()-1, mid=0;
if(R==0) return nums[R];
int result = INT_MAX;
while(nums[L] >= nums[R] && L<R){
if(R-L == 1) return nums[R];
mid = (L+R)/2;
if(nums[mid]==nums[L] && nums[mid]==nums[R]){
L++; R--;
result = min(nums[L], nums[R]);
continue;
}
else if(nums[mid] >= nums[L]) L = mid;
else if(nums[mid] <= nums[R]) R = mid;
result = min(result, nums[mid]);
}
return min(result,nums[mid]);
}
};
把書上的寫法改成了遞歸(我自己的做法也可以改,讀者可以自己試着改一下,這裏我不展示了)
class Solution {
public:
int help(vector<int>& nums, int left, int right){
int result = nums[left];
for(int i=left+1; i<=right; i++){
result = min(result, nums[i]);
}
return result;
}
int find(vector<int>& nums, int left, int right, int mid){
if(nums[left]<nums[right]) return nums[mid];
if(right-left==1) return nums[right];
mid = (left+right)/2;
if(nums[mid]==nums[left] && nums[mid]==nums[right]){
return help(nums, left, right);
}
else if(nums[mid]>=nums[left]) left = mid;
else if(nums[mid]<=nums[right]) right = mid;
return find(nums, left, right, mid);
}
int findMin(vector<int>& nums) {
if(nums.size()==1) return nums[0];
return find(nums, 0 ,nums.size()-1, 0);
}
};