https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/
假设按照升序排序的数组在预先未知的某个点上进行了旋转。注意,该数组可能存在重复元素。
( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。
编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。
示例:
例 1:
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
对于不含重复元素的旋转数组的搜索,我们可以将时间复杂度压缩到 O(logn) 量级,但一旦存在重复元素,在极端情况下,会使得运行时间达到线性时间。(因为无法判断重复元素的部分在左侧还是在右侧)
方法一:线性查找。
遍历数组,寻找 target.
方法二:二分查找。
设置两个变量 left = 0, right = nums.size() - 1, 比较 nums[left] 与 nums[right] 的大小来决定下一步:
代码:
class Solution {
public:
void noRotated( vector<int>& nums, int& target, int& left, int& right, int& middle){ //没有旋转时二分
if( nums[middle] > target)
right = middle;
else if( nums[middle] < target)
left = middle + 1;
}
void yesRotated( vector<int>& nums, int& target, int& left, int& right, int& middle){ //旋转时二分
if( nums[middle] <= nums[right]) // [middle, right]未旋转
if( nums[middle] < target && nums[right] >= target)
left = middle + 1;
else
right = middle;
else //[left, middle]未旋转
if( nums[middle] > target && nums[left] <= target)
right = middle;
else
left = middle + 1;
}
bool search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while( left < right){
int middle = left + ( right - left)/2;
// cout<<"left = "<if ( nums[middle] == target)
return true;
if(nums[left] < nums[right]) //未发生旋转
noRotated( nums, target, left, right, middle);
else if( nums[left] == nums[right]){ //可能发生旋转
if( nums[middle] != nums[right]) //发生旋转
yesRotated( nums, target, left, right, middle);
else //[left, middle, right] 中至少有一侧发生旋转
left++; //此处影响了时间复杂度
}
else if( nums[left] > nums[right]) //发生旋转
yesRotated( nums, target, left, right, middle);
}
return left < nums.size() && nums[left] == target;
}
};