题目描述:
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.
For [4, 5, 1, 2, 3]
and target=1
, return 2
.
For [4, 5, 1, 2, 3]
and target=0
, return -1
.
O(logN) time
题目要求用O(logN)的时间,明显就是二分法的思路。但是这种rotate sorted的array怎么用binary search呢?我的想法可能有些复杂(因为要用two-pass才解出来),是先用binary search找到整个数组A的最小值的index,假设是sidx,然后我把A再接上一个A,这样从sidx~sidx+A.size()-1这一段坐标,数值都是正常sorted的。这样用传统的二分法就可以找到target了。
这题需要注意的是2点:
1. 用binary search找最小值时,最小值靠左的情况有两种:A[mid] < A[l](这说明最大值在左边,最小值在包括mid的左边),A[mid] < A[r](这说明mid往右是正常sorted的)。
2. sidx~sidx+A.size()-1有部分index是超出A.size() - 1的,我用%A.size()就可以得到它在0~A.size()-1的index范围内的相应index。
Mycode(AC = 27ms):
class Solution {
/**
* param A : an integer ratated sorted array
* param target : an integer to be searched
* return : an integer
*/
public:
int search(vector<int> &A, int target) {
// write your code here
if (A.size() == 0) return -1;
// find the index of minimum number in A
int l = 0, r = A.size() - 1, sidx = -1;
while (l + 1 < r) {
int mid = (l + r) / 2; // 2
if (A[mid] < A[l] || A[mid] < A[r]) {
r = mid;
}
else {
l = mid;
}
}
sidx = A[l] <= A[r]? l : r;
// concatenate 2 A's, so that index start ~ end
// is fully ordered
int start = sidx, end = sidx + A.size() - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (A[mid % A.size()] == target) {
return mid % A.size();
}
else if (A[mid % A.size()] < target) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
return -1;
}
};