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

88 阅读2分钟

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

前言

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

image.png

一、思路

我们注意题目中提示信息:数组中所有整数都不相同,这意味着我们无需考虑翻转的地方是否发生在相同元素的地方。

我们可以将这个数组想象成一个分开的折线图,如下所示:

image.png

既然要找到 旋转数组的最小值,我们就需要先知道 旋转的位置,也就是说找到新数组中第二次升序的起始位置,如下图所示:

image.png

那如何快速找到这个点呢?我们很明显可以想到 二分法。然后考虑以下几种情况

mid:数组的中间下面

  1. mid 落在第一段升序上,即 nums[mid] > nums[right]

此时丢弃左边即可,如下图所示:

image.png

  1. mid 落在第二段升序上,即

此时丢弃右边即可,如下图:nums[mid] < nums[right]

image.png

经过不断的丢弃左右区间,最终 left == right,下标指向旋转起始的元素。

举个例子

此处以示例中的 nums = {4,5,6,7,0,1,2} 作为例子

  1. 初始化变量:left = 0, right = 6
  2. mid = 3nums[mid] > nums[right]。丢弃左边 left = mid + 1 = 4
  3. mid = 5nums[mid] < nums[right]。丢弃右边 right = mid = 5
  4. mid = 4nums[mid] < nums[right]。丢弃右边 right = mid = 4
  5. 此时 left = right = 4,返回 nums[4] 的值 0 即可

二、实现

实现代码

实现代码中为了避免死循环,在丢弃左部分时需要丢弃包括自身的元素,即 left = mid + 1

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 {
            left = mid + 1;
        }
    }
    return nums[left];
}

测试代码

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

结果

image.png

三、总结

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

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