描述:给定一个有序数组,数组中可重复出现相同数字,然后数组经过旋转后,如{0,1,1,2,2,3,4,4,5,6}旋转后{4,5,6,0,1,1,2,2,3,4};在旋转后的数组中查找给定值key,并返回数组中key值索引,否则返回-1。
思路一:依然使用暴力查找方法,依次从数组首部遍历至尾部,若查找到key值后,返回第一次出现的索引,否则返回-1;
class Solution{
public:
int search(int A[],int n,int value)
{
if(n<1)return -1;
for(int i=0;i<n;i++)
{
if(A[i]==value)
return i;
}
return -1;
}
};
思路二:依然使用二分法,A[mid]与A[first]共有三种大小关系,1.当A[first]<A[mid]时,能保证[first,mid]是递增序列,如{0,1,1,2,2,3,4,4,5,6};2.当A[first]>A[mid]时,能保证[mid,last]是递增序列,如{4,5,6,0,1,1,2,2,3,4};3.当A[first]=A[mid]时,则有两种情况,如{4,4,4,4,4,1,2,2,3,4}或{4,5,6,0,4,4,4,4,4,4},则缩小区间范围,令first++或last--;
class Solution{
public:
int search(int A[],int n,int value)
{
if(n<1)return -1;
int first=0;
int last=n-1;
while(first!=last)
{
int mid=first+(last-first)/2;
if(A[first]<A[mid])//情况1:[first,mid]递增有序
{
if(A[first]<=value&&A[mid]>value)
{
last=mid-1;
}
else
{
first=mid+1;
}
}
else if(A[first]>A[mid])//情况2:[mid,last]递增有序
{
if(A[mid]<value&&value<=A[last])
{
first=mid+1;
}
else
{
last=mid-1;
}
}
else//情况3:两种缩小范围方案
{
first++;//or last--;
}
}
return -1;
}
};