题目描述:在旋转数组中查找一个数,(II中假设有重复元素)
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.
题目分析:先找出旋转数组的分界线(二分),继而继续二分查找该元素。
首先是I的代码
class Solution {
public:
int search(vector<int>& nums, int target) {
int N=nums.size();
if(N==0) return -1;
if(N==1)
{
if(nums[0]!=target) return -1;
else return 0;
}
int sep; //两个有序数组的分割线
if(nums[0]<nums[N-1]) sep=0;
else sep=find_min_bs(nums,N);
if(sep==0) return bs(nums, 0, N-1, target);
if(nums[N-1]<target) return bs(nums, 0, sep-1, target);
else return bs(nums, sep, N-1, target);
}
int find_min_bs(vector<int>& nums, int N)
{
int l=0, r=N-1, m;
while(l<=r)
{
if(r-l==1) return r;
m=(l+r)/2;
if(nums[l]<nums[m]) l=m;
if(nums[r]>nums[m]) r=m;
}
}
int bs(vector<int>& nums, int l, int r, int target)
{
int m;
while(l<=r)
{
m=(l+r)/2;
if(nums[m]==target) return m;
if(nums[m]>target) r=m-1;
if(nums[m]<target) l=m+1;
}
return -1;
}
};
然后是II的代码
class Solution {
public:
bool search(vector<int>& nums, int target) {
int N=nums.size();
if(N==0) return false;
int min_index=find_min_bs(nums,N);//找到最小值的下标
int l=0, r=N-1;
if(target<nums[min_index]) return false;//保证 target >= nums[min_index]
if(min_index==0) //要是数组没有旋转
return bs(nums,0,N-1,target);
if(target<=nums[r]) return bs(nums,min_index,r,target);
if(target<=nums[min_index-1]) return bs(nums,0,min_index-1,target);
return false;
}
int find_min_bs(vector<int>& nums, int N)//找到最小值的下标
{
int l=0, r=N-1, m;
if( nums[r] > nums[l] ) return 0;
while(l<=m)
{
m=(l+r)/2;
if(nums[l]==nums[m] && nums[m]==nums[r]) return search_min_inorder(nums,l,r);//duplicates
if(r-l==1) return r;
if(nums[m]>=nums[l]) l=m;
if(nums[r]>=nums[m]) r=m;
}
}
int search_min_inorder(vector<int>& nums, int l, int r)
//本来应该顺序查找的,但是可能存在1,3,1,1,1这种情况,我的目标是找到3后面1的下标
{
int index=l;
int max_index=l;
for(int i=l+1; i<=r; i++)
{
if(nums[index]>nums[i]) index=i;
if(nums[max_index]<nums[i]) max_index=i;
}
if (max_index>l) return max_index+1;
return index;
}
bool bs(vector<int>& nums, int l, int r, int target)
{
int m;
while(l<=r)
{
m=(l+r)/2;
if(nums[m]==target) return true;
if(nums[m]<target) l=m+1;
else if(nums[m]>target) r=m-1;
}
return false;
}
};