LeetCode 33 - 搜索旋转排序数组 - [二分]

假设按照升序排序的数组在预先未知的某个点上进行了旋转。算法

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。数组

搜索一个给定的目标值,若是数组中存在这个目标值,则返回它的索引,不然返回 -1 。spa

你能够假设数组中不存在重复的元素。code

你的算法时间复杂度必须是 O(log n) 级别。blog

示例 1:排序

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4索引

示例 2:get

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1io

 

在 $a[0 \sim (size-1)]$ 中查找 $x$:class

首先考虑一个状况,数组是空的,那么直接返回 $-1$;

其次,考虑没有进行旋转的状况,这个能够根据 $a[0]<a[size-1]$ 判断,这样的话直接用lower_bound找第一个不小于 $x$ 的位置,这样就能够判断数组 $a$ 中是否存在 $x$;

再次,先用二分找到旋转数组的分界点,而后对两段分别lower_bound查找 $x$。

 

AC代码:

int Srch(const vector<int>& a,int st,int ed,int x)
{
    int l=st, r=ed;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(a[mid]<x) l=mid+1;
        else r=mid;
    }
    if(a[l]!=x) return -1;
    else return l;
}

class Solution
{
public:
    int search(const vector<int>& a,int x)
    {
        if(a.empty()) return -1;
        if(a.front()<a.back())
            return Srch(a,0,a.size()-1,x);

        int l=0, r=a.size()-1;
        while(r-l>1)
        {
            int mid=(l+r)/2;
            if(a[mid]>a.front()) l=mid;
            else if(a[mid]<a.back()) r=mid;
        }

        return max(Srch(a,0,l,x),Srch(a,r,a.size()-1,x));
    }
};
相关文章
相关标签/搜索