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.
Example 1:
Input: nums = [2,5,6,0,0,1,2], target = 0 Output: true
Example 2:
Input: nums = [2,5,6,0,0,1,2], target = 3 Output: false
Constraints:
1 <= nums.length <= 5000
-104 <= nums[i] <= 104
nums
is guaranteed to be rotated at some pivot.-104 <= target <= 104
Follow up: This problem is similar to Search in Rotated Sorted Array, but nums
may contain duplicates. Would this affect the runtime complexity? How and why?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The simplest way to solve this search problem is to just look at every single number and see if it's the one we're looking for. It's like looking for a specific book on a shelf by checking every book one by one.
Here's how the algorithm would work step-by-step:
def search_in_rotated_sorted_array_brute_force(numbers, target):
# Iterate through each number in the list
for current_index in range(len(numbers)):
# If we find the target, return True
if numbers[current_index] == target:
return True
# If target is not found after iterating, return False
return False
The problem is finding if a number exists in a sorted list that has been rotated. The optimal strategy uses a clever way to narrow down the search area in each step, quickly focusing on where the number might be, instead of checking every number.
Here's how the algorithm would work step-by-step:
def search_in_rotated_sorted_array_ii(numbers, target):
start_index = 0
end_index = len(numbers) - 1
while start_index <= end_index:
middle_index = (start_index + end_index) // 2
if numbers[middle_index] == target:
return True
# Handle the case where we can't determine sorted side
if numbers[start_index] == numbers[middle_index] == numbers[end_index]:
start_index += 1
end_index -= 1
continue
# Check if the left side is sorted
if numbers[start_index] <= numbers[middle_index]:
# Target is in the left sorted portion
if numbers[start_index] <= target < numbers[middle_index]:
end_index = middle_index - 1
# Target is in the right unsorted portion
else:
start_index = middle_index + 1
# Left side is not sorted, so the right side must be
else:
# This means the right side is sorted
# Target is in the right sorted portion
if numbers[middle_index] < target <= numbers[end_index]:
start_index = middle_index + 1
# Target is in the left unsorted portion
else:
end_index = middle_index - 1
return False
Case | How to Handle |
---|---|
Empty array | Return false immediately since the target cannot be found in an empty array. |
Null array | Return false immediately since null array is invalid input. |
Array with one element, target matches | Check if the single element equals the target and return true. |
Array with one element, target does not match | Check if the single element equals the target and return false. |
Array with all identical values, target matches | The while loop may need to iterate through the entire array, but it should correctly identify the target. |
Array with all identical values, target does not match | The while loop will iterate through the entire array and return false. |
Rotation point is at the beginning or end of the array (effectively no rotation). | The binary search should function correctly on the effectively sorted array. |
Large array size to check for potential performance issues | Binary search has logarithmic time complexity, so it scales well with large arrays. |