https://leetcode.com/problems/search-in-rotated-sorted-array/
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,
[0,1,2,4,5,6,7]
might become[4,5,6,7,0,1,2]
).You are given a target value to search. If found in the array return its index, otherwise return
-1
.You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0 Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3 Output: -1
有序数列查找外加logn复杂度,那么几乎可以确定是二分查找,但是因为是个旋转数列,所以是二分查找的变形。
在针对[mid]和target不同大小情况下如何移动两端界限是问题的关键,看似复杂,实际上只要把握好二分查找的关键思想——“两端界限之间的区域是可能的解空间(目标不可能落在两端界限之外)”——只要每一次的移动都确保了这个二分不变性即可。以这个思想为基础,可以针对[mid]大于target的情况可以将mid指针与tar虚指针(target存在的合法位置)的位置关系分为两类:1、两者在同一个有序序列中。2、两者跨立在两个各自有序序列中。判断方式很直观,移动方式也很容易想。小于的情况同理。
class Solution {
public:
int search(vector<int>& nums, int target) {
int lo = 0;
int hi = nums.size()-1;
int mid;
while(lo <= hi){
mid = (lo+hi)/2;
//cout << "lo: " << lo << " mid: " << mid << " hi: " << hi << " [mid]: " << nums[mid] << endl;
if(nums[mid] == target) return mid;
else if(nums[mid] > target){ //mid和tar的位置共有三种可能
if(nums[lo] > target && nums[mid] >= nums[lo]){ //mid在左侧,tar在右侧
lo = mid+1;
}else{ //mid与tar在同侧
hi = mid-1;
}
}else{
if(nums[hi] < target && nums[mid] <= nums[hi]){
hi = mid-1;
}else{
lo = mid+1;
}
}
}
return -1;
}
};