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

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

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

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

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

示例 1:

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

示例 2:

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

 

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

首先考虑一个情况,数组是空的,那么直接返回 $-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));
    }
};

 

posted @ 2019-04-26 12:48  Dilthey  阅读(548)  评论(0编辑  收藏  举报