实为Hard
首先这个题有一些很简单的解法,例如优先队列(选择小根堆),再返回第一个值,就得到了解。但是本题要求运用二分查找。
代码:
int minArray(vector<int>& numbers) {
int left=0;
int right=numbers.size()-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(numbers[mid]>numbers[right])
{
left=mid+1;continue;
}
else if(numbers[mid]<numbers[right])
{
right=mid;continue;
}
else
{
right--;
}
}
return numbers[left];
}
首先应该寻找规律解题:
下面我们以1 2 3 4 5这个升序数组为例
vector<int>& nums
旋转之后可能为:
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
首先理解二分查找,需要用到数组中间值nums[mid],再结合旋转数组的局部有序。
可以分析出来如果nums[mid]>nums[right],那么最小值一定在nums[mid+1]到nums[right]之间。
如果nums[mid]<nums[right],那么最小值一定在nums[left]到nums[mid]之间
首先分析到这个地方,大家一定有疑问:为什么一个是mid+1,一个是mid。
我的分析是,如果nums[mid]<nums[right]时,nums[mid]有可能是最小值,不能直接舍弃。
而nums[mid]>nums[right]时,nums[mid]不可能是最小值,可以直接舍弃。
如果nums[mid]==nums[right],那么就把最后值nums[right]舍弃了,将right更新成right-1。