Problem Description:
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.
分析:
有序数组的查找直接使用二分查找很方便,所以旋转之后的数组要利用二分搜索的原理需要判断哪一部分仍然是有序的,然后确定在哪一部分继续搜索。具体判断方法如下:
(1)如果target==A[mid],那么mid就是我们要的结果,直接返回;
(2)如果A[begin]<=A[mid],那么说明从begin到mid一定是有序的,同样只需要判断target是否在这个范围内,如果是则把右边缘移到mid-1,否则就target在另一半,即把左边缘移到mid+1。
(3)如果A[begin]>A[mid],那么说明从mid到last一定是有序的(没有受到rotate的影响),那么我们只需要判断target是不是在mid到last之间,如果是则把左边缘移到mid+1,否则就target在另一半,即把右边缘移到mid-1。
代码如下:
class Solution {
public:
int binarysearch(int a[],int begin,int last,int target)
{
if(begin>last)
return -1;
int mid=(begin+last)/2;
if(a[mid]==target)
return mid;
if(a[begin]<=a[mid]) //这里一定要加上“=”,例子:3,1中寻找3
{
if(target>=a[begin]&&target<a[mid])
return binarysearch(a,begin,mid-1,target);
else
return binarysearch(a,mid+1,last,target);
}
else
{
if(target>a[mid]&&target<=a[last])
return binarysearch(a,mid+1,last,target);
else
return binarysearch(a,begin,mid-1,target);
}
}
int search(int A[], int n, int target) {
int flag=-1;
if(n==0)
return -1;
flag=binarysearch(A,0,n-1,target);
return flag;
}
};
下面是非递归的代码:
class Solution {
public:
int search(int A[], int n, int target) {
int begin = 0, last = n-1;
while (begin <= last)
{
int mid =(begin + last) / 2;
if (A[mid] == target)
return mid;
if (A[begin] <= A[mid])
{
if (A[begin] <= target && target < A[mid])
last = mid-1;
else
begin = mid + 1;
}
else
{
if (A[mid] < target && target <= A[last])
begin = mid + 1;
else
last = mid-1;
}
}
return -1;
}
};