这题应该是Binary Search题里面最经典的一道了。
注意它跟Rotated Sorted Array里面找minimum要复杂一些。找minimum的题没有target,只需要把A[mid]跟A[start]比较就可以知道是在第二象限还是第四象限,从而把数据分为OOOOXXXX两部分继续二分。
而这道题目需要把A[mid]和target两个值都跟A[start]比较。所以有很多种情况。
case 1: A[mid]==target 直接返回mid即可。
case 2: A[mid]>A[start] && target<A[start] 这种情况说明mid在第一象限,target在第四象限,扔左半边即可。
case 3: A[mid]<A[start] && target>A[start] 这种情况说明mid在第四象限,target在第二象限,扔右半边即可。
case 4: A[mid]<A[start] && target<A[start] 这种情况说明mid在第四象限,target也在第四象限。这个就回到经典的Binary Search了。我们再比较A[mid]和target。如果A[mid]>target,扔右半边,否则扔左半边。
case 5: A[mid]>A[start] && target>A[start] 这种情况说明mid在第一象限,target也在第一象限。比较A[mid]和target。如果A[mid]>target,扔右半边,否则扔左半边。所以case 4和case 5可以合并。
代码如下:
int search(vector<int> &A, int target) {
if (A.size()==0) return -1;
int start=0, end=A.size()-1;
if (A[start]==target) return start;
if (A[end]==target) return end;
while(start+1<end) {
int mid=start+(end-start)/2;
if (A[mid]==target) return mid;
if (A[mid]>A[start] && target<A[start]) start=mid;
if (A[mid]<A[start] && target>A[start]) end=mid;
if ((A[mid]<A[start] && target<A[start]) || (A[mid]>A[start] && target>A[start])) {
if (A[mid]>target) end=mid;
else start=mid;
}
}
if (A[start]==target) return start;
if (A[end]==target) return end;
return -1;
}
注意:
1)应该把A[mid]和target都跟A[start]比。把A[mid]跟A[start]比,然后A[mid]跟target比是不对的。比如说A[mid]>A[start] (第二象限),A[mid]>target,但我们并不知道target是落在第二象限还是第四象限!
2) 我们一开头需要比较A[start]和A[end]是不是已经等于target。否则A[]={1,2,3},start=0, end=2, mid=1, 然后几个if又都不满足,陷入死循环。
二刷:
class Solution {
public:
/**
* @param A: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
int search(vector<int> &A, int target) {
int n = A.size();
if (n == 0) return -1;
int start = 0, end = n - 1;
if (A[start] == target) return start;
if (A[end] == target) return end;
while(start + 1 < end) {
int mid = start + (end - start) / 2;
if (A[mid] == target) return mid;
if (A[mid] > A[start]) {
if (target < A[mid] && target > A[start]) end = mid;
else start = mid;
}
if (A[mid] < A[start]) {
if (target > A[mid] && target < A[end]) start = mid;
else end = mid;
}
}
if (A[start] == target) return start;
if (A[end] == target) return end;
return -1;
}
};
三刷
class Solution {
public:
/**
* @param A: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
int search(vector<int> &A, int target) {
int n = A.size();
if (n == 0) return -1;
int start = 0, end = n - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (A[mid] < A[start] && target > A[start]) {
end = mid;
} else if (A[mid] > A[start] && target < A[start]) {
start = mid;
} else if ((A[mid] > A[start] && target >= A[start]) ||
(A[mid] < A[start] && target < A[start])) {
if (A[mid] > target) {
end = mid;
} else if (A[mid] < target) {
start = mid;
} else {
return mid;
}
}
}
if (A[end] == target) return end;
if (A[start] == target) return start;
return -1;
}
};
上面可以简化为:
class Solution {
public:
/**
* @param A: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
int search(vector<int> &A, int target) {
int n = A.size();
if (n == 0) return -1;
int start = 0, end = n - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (A[mid] < A[start] && target > A[start]) {
end = mid;
} else if (A[mid] > A[start] && target < A[start]) {
start = mid;
} else {
if (A[mid] > target) {
end = mid;
} else if (A[mid] < target) {
start = mid;
} else {
return mid;
}
}
}
if (A[end] == target) return end;
if (A[start] == target) return start;
return -1;
}
};
四刷: <= end就表示在右分支,> end表示在左分支。
class Solution {
public:
/**
* @param a: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
int search(vector<int> &a, int target) {
int aSize = a.size();
if (aSize == 0) return -1;
int start = 0, end = aSize -1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if ((target <= a[end] && a[mid] <= a[end]) ||
(target > a[end] && a[mid] > a[end])) {
if (target < a[mid]) {
end = mid;
} else {
start = mid;
}
} else if (target <= a[end] && a[mid] > a[end]) {
start = mid;
} else {
end = mid;
}
}
if (a[start] == target) return start;
if (a[end] == target) return end;
return -1;
}
};
五刷:
class Solution {
public:
/**
* @param a: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
int search(vector<int> &a, int target) {
int len = a.size();
if (len == 0) return -1;
int start = 0, end = len - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (a[mid] <= a[end])
{
if (target >= a[mid] && target <= a[end]) {
start = mid;
} else {
end = mid;
}
} else {
if (target <= a[mid] && target > a[end]) {
end = mid;
} else {
start = mid;
}
}
}
if (a[end] == target) return end;
if (a[start] == target) return start;
return -1;
}
};
六刷
class Solution {
public:
/**
* @param a: an integer rotated sorted array
* @param target: an integer to be searched
* @return: an integer
*/
int search(vector<int> &a, int target) {
int n = a.size();
if (n == 0) return -1;
int start = 0, end = n - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
// if (a[mid] == target) return mid;
if (a[mid] > a[start]) { //mid is in the left part
if (a[start] <= target && target <= a[mid]) { //target is b/w start and mid
end = mid;
} else { //target is b/w mid and end
start = mid;
}
} else { //mid is in the right part
if (a[mid] <= target && target <= a[end]) { //target is b/w mid and end
start = mid;
} else {
end = mid;
}
}
}
if (a[start] == target) return start;
if (a[end] == target) return end;
return -1;
}
};