Question33–Search in Rotated Sorted Array
给你一个按升序排列的“循环数组”(元素各不相同),即最小元素可以在数组的任意位置。eg:[1,2,3,4,5];[4,5,1,2,3]; []; [1]。同时给你一个目标元素target,返回其在数组中的下标。若不在数组中,返回-1。
method 1
从头到尾扫一遍,返回相同元素的下标。
code:
int search(vector<int>& nums, int target) {
for(int i=0; i<nums.size(); i++){
if(nums[i]==target) return i;
}
return -1;
}
复杂度:O(n)
method 2
- 用二分法找到最小元素的下标。
- 然后将target 和数组最后一个元素比较,确定target落在哪一块。
- 然后在一块中用二分查找,返回target下标。
code:
int search(vector<int>& nums, int target) {
int i=0, j=nums.size()-1;
int min;
if(j==-1) return -1;
while(i<j){
int mid=(i+j)/2;
if(nums[j]<nums[mid]) i=mid+1;
else j=mid;
}
min=i;
if(target<nums.back()){
i=min;
j=nums.size()-1;
}
else if(target>nums.back()){
i=0;
j=min-1;
}
else return nums.size()-1;
while(i<=j){
int mid=(i+j)/2;
if(nums[mid]==target) return mid;
else if(nums[mid]>target) j=mid-1;
else i=mid+1;
}
return -1;
}
复杂度: O(log n)
method 3
在method2的基础上改进,在找到最小元素的下标后,直接在原数组上进行二分查找,只不过每次都要加一个最小元素的下标并除以数组长度后取余。
code
int search(vector<int>& nums, int target) {
int i=0, j=nums.size()-1;
int min;
while(i<j){
int mid=(i+j)/2;
if(nums[j]<nums[mid]) i=mid+1;
else j=mid;
}
min=i;
i=0;
j=nums.size()-1;
while(i<=j){
int mid=(i+j)/2;
int realmid=(mid+min)%nums.size();
if(nums[realmid]==target) return realmid;
else if(nums[realmid]>target) j=mid-1;
else i=mid+1;
}
return -1;
}
复杂度: O(log n)