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
难点在于边界的确定;
总共有六种情况,罗列出来就行,但是要注意
-
mid不是n/2
-
注意边界等于target的情况
-
结合边界处理n = mid还是mid-1 同理s
class
Solution {
public
:
int
search(vector<
int
>& nums,
int
target) {
int
n = nums.size();
if
(n == 0)
return
-1;
int
index = -1;
int
s = 0;
while
(s < n){
int
mid = s + (n - s)/2; // mid = (s+n)/2
if
(nums[mid] == target){
index = mid;
break
;
}
if
((nums[s] <= target && target < nums[mid] && nums[s] <= nums[mid]) ||
(nums[s] <= target && target > nums[mid] && nums[s] > nums[mid]) ||
(nums[s] >= target && target < nums[mid] && nums[s] > nums[mid])
)
n = mid;
else
s = mid + 1;
}
return
index;
}
};
还有一种方法是找到分界点,
class
Solution {
public
:
int
search(
int
A[],
int
n,
int
target) {
int
lo=0,hi=n-1;
// find the index of the smallest value using binary search.
// Loop will terminate since mid < hi, and lo or hi will shrink by at least 1.
// Proof by contradiction that mid < hi: if mid==hi, then lo==hi and loop would have been terminated.
while
(lo<hi){
int
mid=(lo+hi)/2;
if
(A[mid]>A[hi]) lo=mid+1;
else
hi=mid;
}
// lo==hi is the index of the smallest value and also the number of places rotated.
int
rot=lo;
lo=0;hi=n-1;
// The usual binary search and accounting for rotation.
while
(lo<=hi){
int
mid=(lo+hi)/2;
int
realmid=(mid+rot)%n;
if
(A[realmid]==target)
return
realmid;
if
(A[realmid]<target)lo=mid+1;
else
hi=mid-1;
}
return
-1;
}
};