线性探测+二分查找
本题和 力扣(LeetCode)33. 搜索旋转排序数组(C++) 的唯一区别是有重复元素,思考我们之前的二分条件,是根据 n u m s [ 0 ] nums[0] nums[0] 和 n u m s [ m i d ] nums[mid] nums[mid] 判断 m i d mid mid 哪一端有序,但是现在可能出现 n u m s [ 0 ] = n u m s [ m i d ] = n u m s [ r ] nums[0]=nums[mid] =nums[r] nums[0]=nums[mid]=nums[r] ,再按照 n u m s [ m i d ] nums[mid] nums[mid] 和 n u m s [ 0 ] nums[0] nums[0] 判断有序,已经不成立了。考虑去除 n u m s nums nums 末尾等于 n u m s [ 0 ] nums[0] nums[0] 的数,避免特例,这样就可以按照 33 33 33 题那样二分了。
class Solution {
public:
bool search(vector<int>& nums, int target) {
int r = nums.size()-1;
while(r>=0&&nums[0]==nums[r]) r--;
if(r<0) return nums[0]==target;
int l = 0;
while(l<=r){
int mid = l+((r-l)>>1);
if(nums[0]<=nums[mid]){//左端有序
if(target>=nums[0]&&nums[mid]>=target) r = mid -1;
else l = mid + 1;
}else{
if(target<nums[0]&&nums[mid]<target) l = mid + 1;
else r = mid - 1;
}
}
if(nums.size()==l) return false;
return nums[l]==target;
}
};
时间复杂度 O ( n ) O(n) O(n) ,线性探测的最坏时间复杂度 O ( n ) O(n) O(n) 。
空间复杂度 O ( 1 ) O(1) O(1) ,只用到常量级空间 。
致语
理解思路很重要。
欢迎读者在评论区留言,答主看到就会回复的。