剑指 Offer 11(154. 寻找旋转排序数组中的最小值 II). 旋转数组的最小数字(实为Hard)

本文探讨了一种利用二分查找算法在旋转有序数组中寻找最小值的方法。通过分析不同情况,如`nums[mid]>nums[right]`和`nums[mid]<nums[right]`,确定了更新左指针或右指针的条件。对于`nums[mid]==nums[right]`的情况,将右指针右移一位。该算法巧妙地减少了搜索范围,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

实为Hard

首先这个题有一些很简单的解法,例如优先队列(选择小根堆),再返回第一个值,就得到了解。但是本题要求运用二分查找。

代码:

 int minArray(vector<int>& numbers) {
        int left=0;
        int right=numbers.size()-1;
       while(left<right)
       {
           int mid=left+(right-left)/2;
           if(numbers[mid]>numbers[right])
           {
               left=mid+1;continue;
           }
           else if(numbers[mid]<numbers[right])
           {
               right=mid;continue;
           }
           else
           {
               right--;
           }
       }
        return numbers[left];
    }

首先应该寻找规律解题:

下面我们以1 2 3 4 5这个升序数组为例

vector<int>&  nums

旋转之后可能为:

1  2  3  4  5

2  3  4  5  1

3  4  5  1  2

4  5  1  2  3

5  1  2  3  4

首先理解二分查找,需要用到数组中间值nums[mid],再结合旋转数组的局部有序。

可以分析出来如果nums[mid]>nums[right],那么最小值一定在nums[mid+1]到nums[right]之间。

如果nums[mid]<nums[right],那么最小值一定在nums[left]到nums[mid]之间

        首先分析到这个地方,大家一定有疑问:为什么一个是mid+1,一个是mid。

我的分析是,如果nums[mid]<nums[right]时,nums[mid]有可能是最小值,不能直接舍弃。

而nums[mid]>nums[right]时,nums[mid]不可能是最小值,可以直接舍弃。

如果nums[mid]==nums[right],那么就把最后值nums[right]舍弃了,将right更新成right-1。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值