力扣第154题-寻找旋转排序数组中的最小值 II

145 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情

前言

力扣第154题 寻找旋转排序数组中的最小值 II 如下所示:

image.png

一、思路

这一题与前面一题力扣第153题-寻找旋转排序数组中的最小值非常的相似,唯一不同的就是:这一题的数组中含有重复的元素。

题目很长,我们可以简单的总结一下,按照下面三步分解:

  1. 有一个升序数组 nums = [a0, a1, ..., an]

  2. 经过 m 次旋转后变为了 nums = [am, a(m+1), a(m+2) ..., an, a0, a1, a2, ..., a(m-1)]

  3. 找到原数组中的第一个元素 a0

为了更进一步的理解题目,我们可以将题目以图形的形式表示出来。我们假设一个经过旋转过后,有重复元素的数组如下图所述:

image.png

我们的目的就是找到未旋转前的第一个元素,如下图所示:

image.png

至于具体实现的方式,还是与上一题保持一致,都使用 二分法。不过值得注意的是,需要特殊处理中间元素与有边界值相等的情况。当 nums[mid] == nums[right] 时,我们可以丢弃右边界,因为原数组的第一个元素一定在旋转过后的数组的左侧。就像下面这种情况,我们要选择丢弃右边界。

image.png

二、实现

实现代码

实现代码与思路中保持一致。所谓丢弃右边界的元素就是让右边界的下标减一即可。

public int findMin(int[] nums) {
    int left = 0;
    int right = nums.length-1;
    while (left < right){
        int mid = (left + right)/2;
        if (nums[mid] < nums[right]){
            right = mid;
        }else if (nums[mid] > nums[right]){
            left = mid + 1;
        } else {
            right--;
        }
    }
    return nums[left];

}

测试代码

public static void main(String[] args) {
    int[] nums = {5, 6, 7, 0, 1, 4, 4};
    new Number154().findMin(nums);
}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~