Suppose a sorted array 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.
解题思路:数组的查找一般可以使用二分查找法,但是这道题里的数组已经被旋转了,因此需要在二分查找的基础上加入一些限制条件:我们可以考虑一个升序排列的整形序列A[n],带查找目标为target,设low=0,high=n-1,该序列被旋转以后,如果从按照二分查找的方法从中间选取一个值A[mid](mid=(low+high)/2),那么被分出的两个序列中有且仅有一个是升序排列的。在未被旋转的升序序列中,被分出的两个序列都是升序排列且右边序列的值总比左边序列的值大,只需要通过target<A[mid]或target>A[mid]就能选出下一个进行搜索的序列。但由于序列被旋转以后无法保证右边的序列值总比左边的序列值大,我们不能单从target<A[mid]或target>A[mid]来选定下一个进行搜索的序列:比如,有可能target<A[mid]但右边序列不是升序的(即右边序列中包含比A[mid]小的元素),此时target可能位于右边的升序序列中。为了处理这种可能性,我们需要将A[low]和A[high]作为临界条件一起进行判断:如果A[low]<A[mid],说明左边序列是升序排列的,此时若满足(A[mid]>target)&&(A[low]<=target),即说明target不会出现在右边,接下来的迭代对左边序列进行搜索即可;如果A[low]<A[mid]但不满足(A[mid]>target)&&(A[low]<=target),说明target不可能在左边,接下来对右边序列进行搜索。另一方面,如果(A[low]>A[mid]),说明左边序列不是升序,右边序列是升序排列,因此对(A[mid]<target)&&(A[high]>=target)进行判断,若满足,则对右边序列进行搜索,否则搜索左边序列。具体代码如下所示:
代码:
class Solution {
public:
int search(int A[], int n, int target) {
int high,low,mid;
low=0;
high=n-1;
while(low<high){
mid=(low+high)/2;
if(A[mid]==target)return mid;
if(A[low]<A[mid]){
if((A[mid]>target)&&(A[low]<=target)){
high=mid-1;
}else{
low=mid+1;
}
}else if(A[low]>A[mid]){
if((A[mid]<target)&&(A[high]>=target)){
low=mid+1;
}else{
high=mid-1;
}
}else if(A[high]==target){
return high;
}else{
return -1;
}
}
if(A[low]==target){
return low;
}else{return -1;}
}
};