You are given an array of length n which was originally sorted in non-decreasing order (not necessarily with distinct values). It has now been rotated between 1 and n times. For example, the array nums = [1,2,3,4,5,6] might become:
[3,4,5,6,1,2] if it was rotated 4 times.[1,2,3,4,5,6] if it was rotated 6 times.Given the rotated sorted array nums and an integer target, return true if target is in nums, or false if it is not present.
You must decrease the overall operation steps as much as possible.
Example 1:
Input: nums = [3,4,4,5,6,1,2,2], target = 1
Output: trueExample 2:
Input: nums = [3,5,6,0,0,1,2], target = 4
Output: falseConstraints:
1 <= nums.length <= 5000-10,000 <= target, nums[i] <= 10,000nums is guaranteed to be rotated at some pivot.Before attempting this problem, you should be comfortable with:
The simplest approach is to scan every element until we find the target. This ignores the sorted structure but guarantees correctness. Since we only need to know if the target exists, we return immediately upon finding it.
true.false.A rotated sorted array with duplicates still has a useful property: at least one half (left or right of mid) is always sorted. We can determine which half is sorted and check if the target lies within that range. The tricky case is when nums[l] == nums[m], which means we cannot tell which side is sorted. In this case, we simply increment l to skip the duplicate and try again.
l = 0 and r = n - 1.l <= r:m = l + (r - l) / 2.nums[m] equals the target, return true.nums[l] < nums[m], the left half is sorted:[nums[l], nums[m]), search left by setting r = m - 1.l = m + 1.nums[l] > nums[m], the right half is sorted:(nums[m], nums[r]], search right by setting l = m + 1.r = m - 1.nums[l] == nums[m]), increment l to skip the duplicate.false if the loop ends without finding the target.class Solution:
def search(self, nums: List[int], target: int) -> bool:
l, r = 0, len(nums) - 1
while l <= r:
m = l + (r - l) // 2
if nums[m] == target:
return True
if nums[l] < nums[m]: # Left portion
if nums[l] <= target < nums[m]:
r = m - 1
else:
l = m + 1
elif nums[l] > nums[m]: # Right portion
if nums[m] < target <= nums[r]:
l = m + 1
else:
r = m - 1
else:
l += 1
return FalseWhen nums[l] == nums[m], you cannot determine which half is sorted. Simply incrementing l by one is the correct approach, but forgetting this case or trying to apply normal binary search logic will produce incorrect results. This case is what distinguishes this problem from the version without duplicates.
When checking if the target lies in the sorted half, using incorrect comparison operators is a common mistake. For the left sorted portion, use nums[l] <= target < nums[m]. For the right sorted portion, use nums[m] < target <= nums[r]. Missing the equals sign on the boundary elements will cause the algorithm to miss valid targets.
Unlike the non-duplicate version, this problem has O(n) worst-case time complexity when all elements are duplicates except one. Assuming O(log n) performance and not accounting for this edge case in time-sensitive applications can lead to timeout issues.