力扣HOT100之二分查找:153. 寻找旋转排序数组中的最小值
这道题是上一道题:33. 搜索旋转排序数组的前置题,有点没看懂力扣为什么要这样安排题目顺序,应该把这道题按排在前面才对啊。。。这道题的思路已经在上一道题的思路中说过了,这里就直接复制粘贴上一篇博客中的内容了。
我们阅读完题目不难看出,经过旋转后,数组nums
有两种可能的状态:
nums
被分为两个局部有序的子数组,每一个子数组都是严格递增的,此时第一个数组中的所有值均大于第二个数组中的最大值;nums
依旧保持整体有序
因此我们需要利用二分查找来判断,定义left = 0
,right = nums.size() - 1
,使用左闭右开的搜索范围([left, right)
),注意,此时nums
的最后一个元素始终都不在查找范围内,因为我们需要不断将中间值与num
最后一个元素进行比较,以确定最小值与中间值的位置关系。
1.当nums[mid] > nums.back()
时,说明mid
此时一定在第一个数组中,因为nums[mid]
比第二个数组的最大值都更大,不可能落在第二个数组中,此时数组的最小元素一定在mid
的右边,此时我们更新搜索区间的左边界,left = mid + 1
2.当nums[mid] <= nums.back()
时,说明mid
此时一定在第二个数组中,因为nums.back()
比第一个数组的任意元素都更小,而nums[mid]
比nums.back()
还小,不可能落在第一个数组,此时数组的最小元素一定在mid
的左边,此时我们更新搜索区间的右边界,right = mid
我们使用一个while
循环来寻找最小元素的位置,由于我们采用的是左闭右开的查找方式,因此区间合法的条件是left < right
,当循环结束后left == right
,此时nums[left]
或者nums[right]
都是最小值。
class Solution {
public:int findMin(vector<int>& nums) {int left = 0, right = nums.size() - 1; //[left, right)int mid;while(left < right){mid = (left + right) / 2;if(nums[mid] > nums.back()) //最小值在mid的右边left = mid + 1;else right = mid; //最小值在mid的左边}return nums[left];}
};