【二分查找】LeetCode 153. 寻找旋转排序数组中的最小值
题目链接
思路
首先分析一下旋转数组可能有的状态:
- 左 < 中 < 右,此时最小值肯定在左边,应当收缩右边界
- 左 < 中,中 > 右,此时最小值肯定在右半段,应当收缩左边界
- 左 > 中,中 < 右,此时最小值肯定在左半段,应当收缩右边界
分析这三种状态可以发现,中值小于右值时收缩右边界,否则收缩左边界。
那么当中值等于右值时呢?因为本题没有重复元素且使用的是地板除,即 mid 更靠近 left,所以当中值与右值相等时说明 \(left = right\),此时早已退出循环了。
代码
class Solution {
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right){
// 经典操作防止溢出
// 地板除,mid更靠近left
int mid = (right - left) / 2 + left;
// 中值 > 右值,最小值在右半边,收缩左边界
if(nums[mid] > nums[right]){
left = mid + 1;
}else{
// 中值 < 右值,最小值在左半边,收缩右边界
// 因为中值 < 右值,中值也可能是最小值,右边界只能取到mid处
right = mid;
}
}
return nums[left];
}
}