LeetCode 33 Search in Rotated Sorted Array
思路
Sorted Array被分为2部分,左边一部分nums[0]...nums[t]递增,右边一部分nums[t+1]...nums[nums.size() - 1]递减,其中nums[t+1] < nums[t]。通过与nums[0]比较,可知变量target可能在左边或右边。如果target < nums[0],则可能在右边;否则,可能在左边。
由于题目要求在O(log n)时间内实现,自然想到二分查找。二分查找通过与nums[mid]比较来更新搜索区间。
case 1: 如果 (target < nums[0]) && (nums[mid] < nums[0]),则target与nums[mid]都分布在右边。
case 2: 如果 (target >= nums[0]) && (nums[mid] >= nums[0]),则target与nums[mid]都分布在左边。
以上两种情况可以通过(target < nums[0]) == (nums[mid] < nums[0])合并。
case 3: 如果 target < nums[0] 且 不满足(target < nums[0]) == (nums[mid] < nums[0]),则target在右边,nums[mid]在左边。此时应该调整搜索区间的下边界。可以将nums[mid]修改为INT_MIN实现。
Example: [-inf, -inf, -inf, -inf, -inf, -inf, 0, 1, 2, 3, 4, 5, 6, 7],如此修改后,整个Rotated Sorted Array变有序了。
case 4: 如果 target >= nums[0] 且 不满足(target < nums[0]) == (nums[mid] < nums[0]),则target在左边,nums[mid]在右边。此时应该调整搜索区间的上边界。可以将nums[mid]修改为INT_MAX实现。
Example: [12, 13, 14, 15, 16, 17, inf, inf, inf, inf, inf, inf, inf, inf]
代码
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size(), mid, comp;
while (left < right) {
mid = (left + right) >> 1;
if ((nums[mid] < nums[0]) == (target < nums[0]))
comp = nums[mid];
else if (nums[0] <= target)
comp = INT_MAX;
else comp = INT_MIN;
if (target > comp)
left = mid + 1;
else if (target < comp)
right = mid;
else return mid;
}
return -1;
}
};