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)