假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
示例 1:
输入: [3,4,5,1,2]
输出: 1
示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0
二分查找,通过左大神的算法书!
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
using namespace std;
/* 测试数组: [4,5,6,7,1,2,3] */
class Solution {
public:
int findMin(vector<int>& nums) {
int low = 0;
int high = nums.size()-1;
int mid=0;
while(low < high){
cout<<"low:"<<low<<" high:"<<high<<endl;
if(low == high-1){
break;
}
/* 说明目前已经在递增序列当中,最小值为nums[low] */
if(nums[low] < nums[high]){
return nums[low];
}
mid = low + (high-low)/2;
/* mid位置在后半段,最小值一定在区间[low,mid] */
if(nums[low] > nums[mid]){
high = mid;
continue;
}
/* mid位置在前半段,最小值一定在区间[mid,high] */
if(nums[mid] > nums[high]){
low = mid;
continue;
}
/*
* 三种情况都不符合:
* 1.nums[low] >= nums[high]
* 2.nums[low] <= nums[mid]
* 3.nums[mid] <= nums[high]
* 推出: nums[low] = nums[mid] = nums[high]
*
* 此时我们可以遍历low到mid,计数器假设为i
* 1.如果nums[i]>nums[low],也就是 nums[i]<nums[mid],出现递减,则nums[i]为最小值
* 2.如果nums[i]>nums[low],也就是 nums[i]>nums[mid],那么最小值一定在区间[low,mid]之间,则令high = mid重新判断
* 3.如果nums[i]==nums[low],则i++,继续判断下一位。
*/
while(low<mid){
if(nums[low]==nums[mid]){
low++;
}
else if(nums[low] < nums[mid]){
return nums[low];
}
else{
high =mid;
break;
}
}
}
return min(nums[low],nums[high]);
}
};
int main(){
vector<int>nums ={4,5,6,7,0,1,2};
Solution *ps = new Solution();
int ret = ps->findMin(nums);
cout<<"ret = "<<ret<<endl;
system("pause");
return 0;
}