33. Search in Rotated Sorted Array

https://leetcode.com/problems/search-in-rotated-sorted-array/

对于一个有序数组,将其元素以某一个元素为轴进行旋转,比如[0,1,2,3,4,5,6,7]可能会变成[4,5,6,7,0,1,2,3]
求这个经过旋转的数组中是否存在有值等于target,如果有的话就返回其下标,如果没有就返回-1,这里假设数组中没有重复值。要求时间复杂度为 (O(logN))

这里和有序数组不同,当取得中间元素时,没法判断target是在左边还是在右边,因此我们需要先找到分界点,即最小值,或者最大值的位置,因为最小值和最大值两边都是有序的,我们只要判断target比最右边的值大还是小就可以确定target在哪一边,然后进而就是普通的二分查找
因此,这里是两个的二分查找的组合

  • 第一个二分查找找到分界点
  • 第二个二分查找找到其下标
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int lo = 0, hi = nums.size()-1;
        if(hi==-1)
            return -1;
        while(lo < hi) // find the minimum first
        {
            int mi = (lo+hi)>>1;
            if(nums[mi] < nums[hi])
                hi = mi;
            else
                lo = mi +1;
        }
        
        if (nums[nums.size()-1] < target) // 如果target比最后一个元素还要大的话,那么它只可能存在左边,因此调整lo 和 hi的值
        {
            lo=0; hi = hi-1;
        }
        else // 如果 target 小于等于最后一个元素,那么它存在右边,从而调整 lo 和 hi的1值
        {
            lo = lo; hi = nums.size()-1;
        }
        
        while(lo < hi)
        {
            int mi = (lo + hi)>>1;
            if (nums[mi] < target)
                lo = mi+1;
            else
                hi = mi;
        }
        return (nums[lo]==target)?lo:-1;
        
    }
};
原文地址:https://www.cnblogs.com/qiulinzhang/p/12528038.html