154. 寻找旋转排序数组中的最小值 II - 力扣(LeetCode)
和153很像,但是数组可以有重复元素,所以更难
leetcode 第 153 题:寻找旋转排序数组中的最小值(C++)_qq_32523711的博客-CSDN博客
153里面我们可以借助nums[mid]的值与nums[0]的大小关系来准确判断如何收缩我们的二分查找范围。
但是这题里面并不完全可以,因为有重复元素,借官方题解的图:
一个包含重复元素的升序数组在经过旋转之后,可以得到下面可视化的折线图:
当nums[mid] > nums[0]的时候:low = mid + 1
当nums[mid] < nums[0]的时候:high = mid - 1
但是当nums[mid] == nums[0]的时候,无法判断怎样收缩区间,比如:
10 10 1 10 10 10 10:应该向左收缩,high = mid - 1
10 10 10 10 10 1 10:应该向右收缩,low = mid + 1
所以无法统一。
官方题解思路:
旋转数组的最小数字 - 旋转数组的最小数字 - 力扣(LeetCode)
** 注意这儿是和nums[high],也即是数组尾元素比较,相等时也是–high**。
class Solution {
public:
int findMin(vector<int>& nums) {
int low = 0, high = nums.size()-1;
while(low <= high){
auto mid = low + ((high - low)>>1);
if(nums[mid] < nums[high]){
if(mid == 0 || nums[mid-1] >= nums[high])
return nums[mid];
else high = mid - 1;
}else if(nums[mid] > nums[high]){
low = mid + 1;
} else
--high;
}
return nums[low];//出来的时候low = mid
}
};