Leetcode——153. 寻找旋转排序数组中的最小值

这篇博客讨论了如何使用二分查找法在局部有序数组中寻找最小值的问题。分析了确定查找区间的方法,明确了何时更新查找区间以及如何判断找到最小值的条件。同时对比了此题与33题搜索旋转排序数组的不同,指出在不同场景下如何调整二分查找策略。
摘要由CSDN通过智能技术生成

概述

题目链接

  • 局部有序数组内查找最小元素,数组内值互不相同

分析

  • 要求 O ( l o g n ) O(logn) O(logn),说明还是需要二分法,并且局部有序也是支持二分操作的

思路

在这里插入图片描述

  • Q1:如何确定下一个查找区间?

    我们每次得到的值是num[mid],我们想要查找的值是min。由左图可知,当mid在1处时,应该查找右区间;当mid在2处时,应该查找左边区间

  • Q2:如何确定mid的位置?

    通过分析,num[mid]可以和num[l]num[r]比较

    • 如果和num[l]比较,num[mid]>时选择右区间;<时选择左区间
    • 如果和num[r]比较,num[mid]>时选择右区间;<时选择左区间
    • 但是注意特殊情况,也就是右图,我们知道num[mid]<num[r]时,左区间;num[mid]>num[l]时选择左区间

    所以为了一致性,选择和num[r]相比

  • Q3:什么时候找到答案?

    因为我们的区间总是根据min值移动,所以当不用再移动区间时,就说明找到了min

    即,l==r时

实现代码

class Solution {
public:
    int findMin(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while ( l < r) {
            int mid = (l + r) / 2;
            if (nums[mid] < nums[r])	// 这里注意选择和num[r]比较而不是num[0]
                r = mid;				// 最小值有可能就是nums[mid]
            else
                l = mid + 1;
        }
        // 当 l == r的时候,就说明找到最小值了
        return nums[l];
    }
};

拓展

33.搜索旋转排序数组的不同之处

  • 此题的targe相当于一个未知的最小值,所以不需要和nums[mid]比较大小,可以根据mid位置直接确定下一个区间

  • 33题的target是确定的,就算知道了mid的位置,还需要比较target和nums[mid]的大小,才能确定下一个区间

    • 在mid的某些情况下,target是可能出现在两个区间的

      就那上面的左图分析,如果mid在2处,target>nums[mid],target是可能出现在mid的左右两个区间的

    所以和左端 or 右端比较都可以,因为根据mid位置是无法直接确定下个区间的


154. 寻找旋转排序数组中的最小值 II的不同之处

  • 154题中,数组内可能有重复的数值,那么num[r]==num[mid]时,是无法确定mid执行的是1处还是2处
  • 但是可以将r-1,因为如果num[r]是最小值,那么num[mid]也是最小值,不会影结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值