【手绘漫画】图解LeetCode之寻找旋转排序数组中的最小值(LeetCode153题)

在这里插入图片描述

图解LeetCode刷题计划

1、写在前面

手绘漫画系列正式上线!!!“图解LeetCode刷题计划” 来了!!!

距离秋招还有:

在这里插入图片描述
希望能多刷点题,今天是第一期,争取每天一期,最多两天,欢迎大家监督我。。。公众号监督最好!!!

在这里插入图片描述
今天要讲解的题目是LeetCode153题,一道经典的面试题,旋转的排序数组。

在这里插入图片描述

2、题目

首先看一下题目,
在这里插入图片描述
从题目给出的信息中,可以获取到的信息有两点:

  1. 数组是排序的;
  2. 数组经过了旋转;

你可能首先想到的是排个序,然后取个 nums[0]
在这里插入图片描述
哈哈,我估计面试官直接就让你 out 了,这种搜索类题目最好还是用二分法!

二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。

在这里插入图片描述

3、正文

首先分析一下情况,一个排序的数组,即原题给出的,0,1,2,4,5,6,7,这没有问题吧。

蓝色是目标,绿色是mid
在这里插入图片描述
然后旋转了,极端情况有两种,分别是最大值在最左侧和最小值在最右侧的情况。

正常情况就很多种了。

根据二分法,先找到 mid,然后向目标移动,比如下图的第一个就是 midright 移动,第二个就是 midleft 移动。
在这里插入图片描述
为什么是这样的呢?

首先,取一个标志,假设取 right 元素,因为最小值偏向左侧。

因为数组本身带有顺序的原因:

  • 如果 mid 元素大于 right 元素,那么说明右侧有小值,而我们寻找的最小值必然也在右侧;
  • 如果 mid 元素小于 right 元素,那么说明右侧是大值,左侧是小值,我们寻找的最小值必然也在左侧;

在这里插入图片描述

4、代码

int findMin(int* nums, int numsSize){
    int left=0;int right=numsSize-1;
    while(right>left){
        int mid=left+(right-left)/2;
        if(nums[mid]>nums[right]){
            left=mid+1;
        }
        else{
            right=mid;
        }
    }
    return nums[left];
}

在这里插入图片描述

5、讨论

提个问题,为什么 leftmid+1,而 right 却是 mid

其实这个问题是我自己比较疑惑的一个点,不过我觉得应该是这样的,因为 mid 更偏向于 left,而不是 right,证明如下,所以,left 是不用担心会错失的问题的,但是 right 却容易错失!!!

在这里插入图片描述
即:

  • 明确 nums[mid]>nums[right],最小值在右半边,收缩左边界,因为中值肯定不是最小值,左边界可以跨过 mid

  • 明确 nums[mid]<nums[right],最小值在左半边,收缩右边界,因为中值也可能是最小值,右边界只能取到 mid

在这里插入图片描述

如果有幸帮到你,请帮我点个【赞】,给个【关注】!如果能顺带【评论】给个鼓励,我将不胜感激。

如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~

回复【数据结构】即可获取我为你准备的大礼

想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~

在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是管小亮

一口吃掉你的打赏,嗝~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值