题目: 一个原本增序的数组被首尾相连后按某个位置断开(如 [1,2,2,3,4,5] → [2,3,4,5,1,2],在第一位和第二位断开),我们称其为旋转数组。给定一个值,判断这个值是否存在于这个为旋转数组中。
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
方法一: 二分查找
class Solution {
public:
bool search(vector<int>& nums, int target) {
int n = nums.size();
if (n == 0) {
return false;
}
if (n == 1) {
return nums[0] = target;
}
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
++l;
--r;
} else if (nums[l] <= nums[mid]) {
if (nums[l] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return false;
}
};
复杂度分析
时间复杂度: O(n),其中 n 是数组 nums 的长度,最坏情况下数组元素均相等且不为 target,我们需要访问所有位置才能得出结果。
空间复杂度: O(1)。
方法二: 二分查找
class Solution {
public:
bool search(vector<int>& nums, int target) {
int start = 0, end = nums.size() - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[start] == nums[mid]) {
// 无法判断哪个区间是增序的
++start;
} else if (nums[mid] <= nums[end]) {
// 右区间是增序的
if (target > nums[mid] && target <= nums[end]) {
start = mid + 1;
} else {
end = mid - 1;
}
} else {
// 左区间是增序的
if (target >= nums[start] && target < nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
}
}
return false;
}
};