LeetCode 33
https://leetcode.cn/problems/search-in-rotated-sorted-array/description/
难度:中等
本题是二分查找的应用,使用红蓝染色法。如果 mid 就是 target 或者在 target 右侧,染为蓝色,如果在 target 左侧,染为红色。
如果数组被旋转了,那么分为左右两段,左边一段的元素大于最后一个元素。
对于节点 i 被染为蓝色分为以下情况:
- 如果 nums[i] > end,也就是 i 在左边这段。那么需要 target 也在左边这段,并且在他左边。
- 如果 nums[i] <= end,也就是 i 在右边这段。那么需要 target 要么在左边这段,要么在右边这段但是在他左边。
由于最后一个元素一定在 target 右边,初始就为蓝色,因此二分区间为 [0, n - 2]。
时间复杂度:O(logn),其中 n 为 nums 的长度。
空间复杂度:O(1),仅用到若干额外变量。
class Solution {
public:
int search(vector<int>& nums, int target) {
int end = nums.back();
auto check = [&](int i) -> bool {
int x = nums[i];
if (x > end) {
return target > end && x >= target;
}
return target > end || x >= target;
};
int left = -1, right = nums.size() - 1; // 开区间 (-1, n-1)
while (left + 1 < right) { // 开区间不为空
int mid = left + (right - left) / 2;
(check(mid) ? right : left) = mid; // 更简洁的写法
}
return nums[right] == target ? right : -1;
}
};