33
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.
81
Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
这是一个有序数组, 所以我们可以尝试使用二分的思路去解决这个问题, 不过需要注意一个问题,使用二分法的时候, 边界问题的判断。 这里由于不太记得住二分法究竟怎么写了, 于是在自己的代码中加了一个补丁, 特别判断一下 start == stop - 1 的情形
而对于 81 题, 由于允许重复, 我们只需要对有重复部分区域采用遍历即可。
class Solution {
public:
int search(vector<int>& nums, int target) {
return helper(nums, 0, nums.size() - 1, target);
}
private:
// x --> [start, stop];
int helper(vector<int>& nums, int start, int stop, int target){
int res = -1;
while (start <= stop){
int mid = start + ((stop - start) >> 1);
if (nums[mid] == target)
return mid;
if (start == stop)
break;
// 我是补丁
if (start == stop - 1){
if (nums[stop] == target)
return stop;
break;
}
if (nums[start] < nums[mid]){
if (nums[start] <= target && nums[mid] > target)
stop = mid - 1;
else
start = mid + 1;
}
else{
if (nums[mid] < target && nums[stop] >= target)
start = mid + 1;
else
stop = mid - 1;
}
}
return res;
}
};
class Solution {
public:
bool search(vector<int>& nums, int target) {
return helper(nums, 0, nums.size() - 1, target) >= 0;
}
private:
// x --> [start, stop];
int helper(vector<int>& nums, int start, int stop, int target){
int res = -1;
while (start <= stop){
int mid = start + ((stop - start) >> 1);
if (nums[mid] == target)
return mid;
if (start == stop)
break;
// 我是补丁
if (start == stop - 1){
if (nums[stop] == target)
return stop;
break;
}
// 遍历搜索
if (nums[start] == nums[mid] || nums[stop] == nums[mid] || nums[start] == nums[stop]){
for (int i = start; i != stop + 1; i++){
if (nums[i] == target)
return i;
}
return -1;
}
if (nums[start] < nums[mid]){
if (nums[start] <= target && nums[mid] > target)
stop = mid - 1;
else
start = mid + 1;
}
else{
if (nums[mid] < target && nums[stop] >= target)
start = mid + 1;
else
stop = mid - 1;
}
}
return res;
}
};
这段代码, 主要是通过先利用二分查找, 找到最小值的位置, 然后根据这个最小值的位置, 可以推算出该旋转数组和该数组之间的转化关系, 利用二分查找即可, what a brilliant solution!!!
class Solution {
public:
int search(int A[], int n, int target) {
int lo=0,hi=n-1;
// find the index of the smallest value using binary search.
// Loop will terminate since mid < hi, and lo or hi will shrink by at least 1.
// Proof by contradiction that mid < hi: if mid==hi, then lo==hi and loop would have been terminated.
while(lo<hi){
int mid=(lo+hi)/2;
if(A[mid]>A[hi]) lo=mid+1;
else hi=mid;
}
// lo==hi is the index of the smallest value and also the number of places rotated.
int rot=lo;
lo=0;hi=n-1;
// The usual binary search and accounting for rotation.
while(lo<=hi){
int mid=(lo+hi)/2;
int realmid=(mid+rot)%n;
if(A[realmid]==target)return realmid;
if(A[realmid]<target)lo=mid+1;
else hi=mid-1;
}
return -1;
}
};
public class Solution {
public int search(int[] A, int target) {
int lo = 0;
int hi = A.length - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (A[mid] == target) return mid;
if (A[lo] <= A[mid]) {
if (target >= A[lo] && target < A[mid]) {
hi = mid - 1;
} else {
lo = mid + 1;
}
} else {
if (target > A[mid] && target <= A[hi]) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
}
return A[lo] == target ? lo : -1;
}
}
由于当发生重复的时候, A[m] == A[l], 可以将 l++, 因为这个l 的值会在后面的内容中再次出现的。。。
bool search(int A[], int n, int key) {
int l = 0, r = n - 1;
while (l <= r) {
int m = l + (r - l)/2;
if (A[m] == key) return true; //return m in Search in Rotated Array I
if (A[l] < A[m]) { //left half is sorted
if (A[l] <= key && key < A[m])
r = m - 1;
else
l = m + 1;
} else if (A[l] > A[m]) { //right half is sorted
if (A[m] < key && key <= A[r])
l = m + 1;
else
r = m - 1;
} else l++;
}
return false;
}