【LeetCode】33. Search in Rotated Sorted Array(C++)
地址:https://leetcode.com/problems/search-in-rotated-sorted-array/
題目:
Suppose an array sorted in ascending order 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.
Your algorithm’s runtime complexity must be in the order of .
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
理解:
這道題裡,給出的陣列是一個有序陣列經過了旋轉,把後面的某些元素移到了最前面,基本的思路應該還是二分查詢,但是具體實現的時候肯定有些不同。
看了三種實現比較清楚,總結一下。
實現1:
在這個實現裡,首先是使用二分查詢找到了最小元素的位置,然後進行二分查詢的時候,每次mid都加上這個偏移量,相當於在邏輯上在一個有序陣列上進行查詢,nb!
這裡並沒有改變l和h的取值方式,而是通過給mid
加一個偏移量的方法來進行比較。
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0, h = nums.size() - 1;
while (l < h) {
int mid = l + (h - l) / 2;
if (nums[mid] > nums[h]) l = mid + 1;
else h = mid;
}
int rot = l;
l = 0;
h = nums.size() - 1;
while (l <= h) {
int mid = l + (h - l) / 2;
int realmid = (mid + rot) % nums.size();
if (nums[realmid] == target) return realmid;
else if (nums[realmid] < target) l= mid + 1;
else h = mid - 1;
}
return -1;
}
};
出處:Concise O(log N) Binary search solution
實現2:
下面的實現,是通過比較改變和target對比的那個陣列值。
對於題中給出的陣列,若要查詢的元素在前半段,可以把後半段都看作是INT_MAX,這樣就可以進行二分查找了。同理,若要查詢的在後半段,把看作是INT_MIN即可。不需要改變原陣列,只需要從邏輯上進行判斷。
若target
和nums[mid]
在nums[0]
的同側,則用nums[mid]和target比較即可,否則,需要
int search(vector<int>& nums, int target) {
int lo = 0, hi = nums.size();
while (lo < hi) {
int mid = (lo + hi) / 2;
double num = (nums[mid] < nums[0]) == (target < nums[0])
? nums[mid]
: target < nums[0] ? -INFINITY : INFINITY;
if (num < target)
lo = mid + 1;
else if (num > target)
hi = mid;
else
return mid;
}
return -1;
}
出處:Clever idea making it simple
實現3:
這種實現也很直觀。
- 如果
nums[mid]>nums[r]
,就說明現在的右半段是兩個升序陣列構成,判斷target的大小需要考慮比nums[mid]
大或``比nums[r]
小。- 如果滿足,說明在右半部分中
- 否則在左半部分中。
- 否則,mid到r是有序的。需要判斷target是否在
nums[mid]
-nums[r]
之間。
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0, r = nums.size() - 1;
while(l <= r){
int mid = l + (r - l) / 2;
if(nums[mid] == target) return mid;
if(nums[mid] > nums[r]){
if(target > nums[mid] || target <= nums[r]) l = mid + 1; // condition for pick right side
else r = mid - 1; // else, pick left side
}else{
if(target <= nums[r] && target > nums[mid]) l = mid + 1; // condition for pick right side
else r = mid - 1; // else, pick left side
}
}
return -1;
}
};
好煩陣列的題