leetcode33

/*题目要求时间复杂度只能是O(logn),所以只需考虑如何二分
按照某个点旋转 其实按照left mid right的增减关系能够确定旋转点在哪个分区
这就可以先logn时间找到旋转的点的位置centre
第二次找索引只需要在旋转位置centre的基础上对索引进行取mod即可*/
class Solution {
public:
    int search(vector<int>& nums, int target) {
         int centre;

         int left , mid , right;
         int len = nums.size();
         left = 0;
         right = len - 1;
         while(left < right){//二分寻找有序数列的旋转位置
            mid = (left + right)/2;
            if(nums[mid] >= nums[left]){//左区递增
              if(nums[mid] > nums[mid + 1]) {centre = mid + 1;break;}
              else                          left = mid + 1;
            }
            else if(nums[mid] <= nums[right]){//右区递增
               if(nums[mid] < nums[mid - 1]) {centre = mid;break;}
               else                           right = mid - 1;
            }
         }

         if(nums[0]  < nums[len - 1])//递增序列 绕空点旋转 特殊的边界情况
            centre = 0;
         
         left = 0;
         right = nums.size() - 1;
         
         while(left <= right){//第二次二分找到target的位置
             if(left == right){
                 if(nums[(left + centre)%len] == target) return (left + centre) % len;
                 else return -1;
             }
           
             mid = (right + left)/2;
             if(nums[(mid + centre)%len] > target)       right = mid - 1;
             else if(nums[(mid + centre)%len] < target)  left = mid + 1;
             else                                        return (mid + centre)%len;
         }
        return -1;
    }
};

 

posted on 2020-10-04 13:49  在苏州的城边  阅读(189)  评论(0编辑  收藏  举报

导航