(必背)旋转数组专题(二分搜索区间定位)(lc33,81,153,154)

二分查找可以按照区间来进行定位,比如说如下图

前半部分的红色区间和后半部分的绿色区间,红色区间的结束点a和绿色区间的开始点b

如果我们要查找红色区间点a,我们可以将二分法写成如下形式

int bs1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (判断条件) l = mid;
        else r = mid - 1;
    }
    return l;
}

反之,如果我们要查找绿色区间的开始点b,我们可以把区间写成如下形式

int bs2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (判断条件) r = mid;    
        else l = mid + 1;
    }
    return l
}

按照以上两种方法,最终分别可以定位到区间a和b

(lc53)假设按照升序排序的数组在预先未知的某个点上进行了旋转。例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] 。

请找出其中最小的元素。

我们可以以nums[0]的值作为判断条件,将数组分为两个区间,前半部分>=nums[0],后半部分小于nums[0]

这样我们就可以定位到区间的分界点

class Solution {
public:
    int findMin(vector<int>& nums) {
        if(nums.size() == 1) return nums[0];
        int l = 0, r = nums.size()-1;
        while(l < r){
            int mid = (l + r + 1) >> 1;
            if(nums[mid] >= nums[0]) l = mid;
            else r = mid - 1;
        }
        if(l == nums.size()-1){  //注意边界情况
            if(nums[l] >= nums[0]) return nums[0];
            else return nums[l];
        }
        return nums[l+1];
    }
};

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值