Question:
Suppose a sorted array 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.
分析:原数组是有序的,经过旋转m步后,求旋转后数组的最小值。
如果数组没有旋转,则第一个元素就是最小值;
如果数组旋转了,那么最小元素可能在除了第一个位置外的其他任意个位置。而且此时数组以最大值为分界点分为两部分,大值部分和小值部分。
则,如果数组旋转了,就采用二分法判断:left,right,mid。如果中间元素大于等于左边元素,则说明最小值在半部分,令left=mid;如果中间元素小于等于右边元素,则说明最小值在左半部分,令right = mid。如果left和right相邻了,则直接比较两个数据的大小即可,也可以直接返回right所指向的值。
但是会有一种特殊的情况,比如0,1,1,1,1; 旋转后为1,0,1,1,1;第一次判断时候,mid值与left和right相等,导致不知道最小值在哪个部分,这种情况就遍历一遍数组,找到最小值。
代码如下:
<span style="font-size:14px;">class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.size() == 0)
return 0;
if(nums.size() == 1)
return nums[0];
int left = 0;
int right = nums.size() - 1;
int mid = left;
while(nums[left] >= nums[right]){
if(left+1 == right){
if(nums[left] < nums[right])
return nums[left];
else
return nums[right];
}
mid = (left+right)/2;
if(nums[mid] == nums[right] && nums[left] == nums[right]){
return minOrder(nums,left,right);
}
if(nums[mid] >= nums[left]){
left = mid;
}
else if(nums[mid] <= nums[right] ){
right = mid;
}
}
return nums[mid];
}
int minOrder(vector<int>& nums,int left,int right){
int min = nums[left];
for(int i = left; i < right; ++i){
if(nums[i] < min)
min = nums[i];
}
return min;
}
};</span>