33. Search in Rotated Sorted Array#
Difficulty: Medium
Link to Problem: To see the Search in Rotated Sorted Array problem on LeetCode, click here!
There is an integer array nums
sorted in ascending order (with distinct values).
Prior to being passed to your function, nums
is possibly rotated at an unknown pivot index k (1 <= 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,5,6,7]
might be rotated at pivot index 3 and become [4,5,6,7,0,1,2]
.
Given the array nums
after the possible rotation and an integer target
, return the index of target
if it is in nums
, or -1
if it is not in nums
.
You must write an algorithm with \(O(log\ n)\) runtime complexity.
Constraints:
1 <= nums.length <= 5000
\(-10^4\) <=
nums[i]
<= \(10^4\)All values of
nums
are unique.nums
is an ascending array that is possibly rotated.\(-10^4\) <=
target
<= \(10^4\)
def search(nums, target):
left, right = 0, len(nums) - 1
# Find the pivot index using binary search
while left < right:
mid = left + (right - left) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
pivot = left
left, right = 0, len(nums) - 1
# Determine which part of the array to search in
if target >= nums[pivot] and target <= nums[right]:
left = pivot
else:
right = pivot
# Perform binary search to find the target
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Explanation:#
The
search
function takes two arguments:nums
, which is the rotated sorted array, andtarget
, which is the value we want to find in the array.We initialize two pointers,
left
andright
, which represent the range in which we are going to perform binary search. Initially,left
is set to 0, andright
is set to the index of the last element in the array (len(nums) - 1
).We start by finding the pivot index using binary search. The pivot index is the index at which the array is rotated. We use a
while
loop to continue the search untilleft
is less thanright
.Inside the loop, we calculate the middle index
mid
using integer division. We then compare the value atmid
with the value atright
. Ifnums[mid]
is greater thannums[right]
, it means the pivot point lies to the right ofmid
, so we updateleft
tomid + 1
. Otherwise, the pivot point lies to the left ofmid
, so we updateright
tomid
. This process continues until we find the pivot index.After finding the pivot index, we have divided the array into two parts: one part is sorted in ascending order, and the other part is also sorted in ascending order but rotated. We need to determine which part of the array contains the target value.
We reset
left
andright
pointers. If the target value is within the range[nums[pivot], nums[right]]
, we setleft
topivot
(the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we setright
topivot
(the end of the sorted part), indicating that we should search in the sorted part.We then perform binary search again within the chosen range (
left
toright
) to find the target element. The binary search continues untilleft
is less than or equal toright
.Inside the binary search loop, we calculate the middle index
mid
and comparenums[mid]
with the target value. If they are equal, we returnmid
as the index of the target element. Ifnums[mid]
is less than the target, we updateleft
tomid + 1
to search in the right half. Ifnums[mid]
is greater than the target, we updateright
tomid - 1
to search in the left half.If we exit the binary search loop without finding the target, we return -1 to indicate that the target is not present in the array.
Test cases#
nums1 = [4, 5, 6, 7, 0, 1, 2]
target1 = 0
result1 = search(nums1, target1)
print(result1)
4
# Example 2:
nums2 = [4, 5, 6, 7, 0, 1, 2]
target2 = 3
result2 = search(nums2, target2)
print(result2)
-1
# Example 3:
nums3 = [1]
target3 = 0
result3 = search(nums3, target3)
print(result3)
-1
Let’s analyze the time and space complexity of the provided code:
Time Complexity:
Finding the pivot index using binary search takes \(O(log\ n)\) time, where ‘\(n\)’ is the number of elements in the array.
After finding the pivot index, performing binary search to find the target element also takes \(O(log\ n)\) time in the worst case.
The dominant factor in the time complexity is the binary search, and since we perform two binary searches sequentially, the overall time complexity of the code is \(O(log\ n)\).
Space Complexity:
The space complexity of the code is very minimal:
We use a constant amount of additional space for variables such as
left
,right
,pivot
, andmid
. These variables do not depend on the input size, so they contribute \(O(1)\) space complexity.The function does not use any additional data structures that scale with the input size.
Therefore, the space complexity of the code is \(O(1)\), which means it has a constant space complexity and does not depend on the size of the input array.
In summary:
Time Complexity: \(O(log\ n)\)
Space Complexity: \(O(1)\)
Challenging Exercises:#
Find Minimum Element in Rotated Sorted Array: Write an algorithm to find the minimum element in a rotated sorted array. This is a variation of the problem where you don’t need to search for a target value but instead find the smallest element.
Search in a Circularly Sorted Array: Consider an array that is sorted in a circular manner (e.g., [4, 5, 6, 7, 0, 1, 2, 3]). Adapt the search algorithm to work for circularly sorted arrays while maintaining \(O(log\ n)\) complexity.