搜索旋转排序数组

这道题用到了二分

能用二分的题目不一定要有序,而是能有将区间一份为二的性质(这里的一分为二,不代表两个区间相等,仅仅是将一个区间分成了两个),只不过在区间里面二分求值刚好需要序列的单调性

思路:

这个题有两段有序的序列,而二分需要知道序列的区间,所以我们要求出两个序列的断点,这里我们可以用二分,之前我们说了二分须有能将区间一分为二的性质,就说明有一个性质一个区间满足,另一个区间不满足,这里我们由题意可知这是一个升序序列,且将较大的序列旋转到前面来,那么是不是前面一个区间都大于等于nums[0],后面一个区间都小于nums[0],ok,这样我们就能找到断点了。

我们模拟一下找出断点的步骤,一开求下标mid,若》=nums[0]则说明mid在上半区间里,而且答案必然在mid的右边或在mid上,这里我们把l=mid。

找到断点后判断 目标值在哪个区间里,同样是根据nums[0]判断,然后二分求下标。

步骤:

1.根据性质是前面一个区间都大于等于nums[0],后面一个区间都小于nums[0],二分求断点

2.判断target在哪个区间内部,改变区间范围

3.二分求target,

注意:

这里写成nums[r], 当数组只有一个元素时, 两个二分查找代码都没有走, 而l在上面被+1, 这时会越界, 而r是length-1还是0, 不会产生越界

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty())return -1;
        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(target>=nums[0])l=0;
        else l=r+1,r=nums.size()-1;
        while(l<r){
            int mid=l+r>>1;
            if(nums[mid]>=target)r=mid;
            else l=mid+1;
        }
        if(nums[r]==target)return l;
        else return -1;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值