假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。
样例
给出[4, 5, 1, 2, 3]和target=1,返回 2
给出[4, 5, 1, 2, 3]和target=0,返回 -1
六十二和六十三题的区别就是数组中有没有重复的数字。
六十二:http://www.lintcode.com/zh-cn/problem/search-in-rotated-sorted-array/
六十三:http://www.lintcode.com/zh-cn/problem/search-in-rotated-sorted-array-ii/
先说没有重复数字的情况
这种搜索类的问题一般都是二分查找法,关键是找到可以使用二分查找的区间,我们首先取数组中间数,如果它比第一个数大,那么它在数组的前半部分,如果比第一个数小,那么它在后半部分,因为前后两半部分都是各自严格递增的。
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.empty()) return -1;
int i = 0, j = A.size() - 1;
while (i <= j) {
int mid = (i + j) / 2;
if (A[mid] == target) return mid;
if (A[mid] > A[i]) {
if (A[i] <= target && target < A[mid]) j = mid - 1;
else i = mid + 1;
}
else {
if (A[mid] < target && target <= A[j]) i = mid + 1;
else j = mid - 1;
}
}
return -1;
}
};
当有重复数字的时候道理是一样的,也是和第一个数比,但是因为有重复数字的存在,因此如果遇到重复数字直接跳过,这就是代码中i++的原因。
class Solution {
/**
* param A : an integer ratated sorted array and duplicates are allowed
* param target : an integer to be search
* return : a boolean
*/
public:
bool search(vector<int> &A, int target) {
// write your code here
if (A.empty()) return false;
int i = 0,j = A.size()-1;
while (i <= j) {
int mid = (i + j) / 2;
if (A[mid] == target) return true;
if (A[mid] > A[i]) {
if (A[i] <= target && target < A[mid]) j = mid - 1;
else i = mid + 1;
}
else if (A[mid] < A[i]) {
if (A[mid] < target && target <= A[j]) i = mid + 1;
else j = mid - 1;
}
else i++;
}
return false;
}
};