LC81. Search in Rotated Sorted Array II¶
Problem Description¶
LeetCode Problem 81: There is an integer array nums
sorted in non-decreasing order (not necessarily with distinct values).
Before being passed to your function, nums
is rotated at an unknown pivot index k
(0 <= k < nums.length
) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(0-indexed). For example, [0,1,2,4,4,4,5,6,6,7]
might be rotated at pivot index 5
and become [4,5,6,6,7,0,1,2,4,4]
.
Given the array nums
after the rotation and an integer target
, return true
if target
is in nums
, or false
if it is not in nums
.
You must decrease the overall operation steps as much as possible.
Clarification¶
- sorted and rotated
- have duplicates
Assumption¶
Solution¶
Approach - Binary Search¶
This is a follow-up problem to LC33 - Search in Rotated Sorted Array. The difference is that it contains duplicates. We can still divide the array into a sorted part and a unsorted part and then search. Due to duplicates,
- For situation 1 in LC33,
nums[left] <= nums[mid] <= nums[right]
, whennums[left] == nums[mid] == nums[right]
, we don’t know which part (left or right) is sorted. For example,[3,1,3,3,3,3,3]
with left part unsorted and[3, 3, 3, 3, 3, 1, 3]
with right part unsorted. For this case, iftarget != nums[mid]
, we can increase left and decrease right by 1.
class Solution:
def search(self, nums: List[int], target: int) -> bool:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return True
elif nums[left] == nums[mid] and nums[mid] == nums[right]:
left += 1
right -= 1
elif nums[left] <= nums[mid]: # (1)
# [left, mid] non-decreasing
if nums[left] <= target and target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
# [mid, right] non-decreasing
if nums[mid] < target and target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return False
- Add
=
to handle case `left == mid``
Complexity Analysis¶
- Time complexity: \(O(\log n)\) for the average, \(O(n)\) for the worst case
In the worst case, just move left pointer by one, which needs n steps. So the time complexity is \(O(n)\). For the average case, since using binary search, the time complexity is \(O(\log n)\). - Space complexity: \(O(1)\)
Only use limited variables for indices.
Test¶
- Only two numbers, e.g.
[3, 1]
- Test array with `nums[left] == nums[mid]``