/*题目要求时间复杂度只能是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; } };