文章目录
题目
代码(7.19 首刷看解析)
这题的不同在于有重复元素,需要多一步操作。
对于数组中有重复元素的情况,二分查找时可能会有 a [ l ] = a [ m i d ] = a [ r ] a[l]=a[mid]=a[r] a[l]=a[mid]=a[r],此时无法判断区间 [ l , m i d ] [l,mid] [l,mid] 和区间 [ m i d + 1 , r ] [mid+1,r] [mid+1,r] 哪个是有序的。
例如 n u m s = [ 3 , 1 , 2 , 3 , 3 , 3 , 3 ] , t a r g e t = 2 nums=[3,1,2,3,3,3,3],target=2 nums=[3,1,2,3,3,3,3],target=2,首次二分时无法判断区间 [ 0 , 3 ] [0,3] [0,3] 和区间 [ 4 , 6 ] [4,6] [4,6] 哪个是有序的。
对于这种情况,我们只能将当前二分区间的左边界加一,右边界减一,然后在新区间上继续二分查找。
class Solution {
public:
bool search(vector<int>& nums, int target) {
int n = nums.size();
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]) {
l++;
continue;
}
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;
}
};