题目描述
- 这题是 第153题的延伸版本,点击查看题解
题目分析
-
这道题也是寻找排序数组的最小值,但是相比于 153 题,数组中多了可重复的元素
-
这样就会带来一个问题,如果在比较的时候,两个值相等,那是忽略左区间好呢?还是忽略右区间好呢?
-
来分析一下,如果两个元素相等,那就说明数组内含有相等的元素,由于重复元素的存在,就无法直接判断最小值是在中值的左还是右
-
但是我们能够知道 右值 和 中值 是相等的
-
如果 中值 在 最小值 的 左边 那 中值 的左边的值都是相等的,且等于 右值,移动 左值 就会继续重复一次判断,所以移动右值会更好
-
如果 中值 在 最小值 的 右边 那可以移动 右值 让 中值 左移
-
如果 中值 刚好在 最小值 上,那就说明整个数组的值都是一样的
-
综合起来就是,当 中值==右值 时,移动右指针是最佳的选择
-
那么怎么移动呢?
-
要么就是移动到中值,但是现在最小值位置不确定,移动到中值不恰当
-
要么就是一个一个移动,将右值前移,比较适合
解法分析
- 整体为一个循环,然后判断中值和右值的大小关系,移动左右两个指针,直到两指针重合,返回左指针结果即可
代码
class Solution {
public int findMin(int[] nums) {
if (nums.length == 1) return nums[0];
int left = 0;
int right = nums.length -1;
while(left < right){
int mid = (left+right)/2;
if(nums[mid] > nums[right]){
// 中值 比 右值 大,最小值肯定在右边,且中值肯定不是最小值
left = mid + 1;
} else if(nums[mid] < nums[right]){
// 中值 比 右值 小,最小值肯定在左边,中值也可能是最小值
right = mid;
} else {
// 中值 等于 右值 ,不能肯定最小值是在左边还是右边
// 但是能肯定,右值不是最小的值,且右值有一个相同的值
// 所以可以让右值后退,缩小区间
right--;
}
}
return nums[left];
}
}