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
numsare unique.numsis 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
searchfunction 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,
leftandright, which represent the range in which we are going to perform binary search. Initially,leftis set to 0, andrightis 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
whileloop to continue the search untilleftis less thanright.Inside the loop, we calculate the middle index
midusing integer division. We then compare the value atmidwith the value atright. Ifnums[mid]is greater thannums[right], it means the pivot point lies to the right ofmid, so we updatelefttomid + 1. Otherwise, the pivot point lies to the left ofmid, so we updaterighttomid. 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
leftandrightpointers. If the target value is within the range[nums[pivot], nums[right]], we setlefttopivot(the start of the rotated part), indicating that we should search in the rotated part. Otherwise, we setrighttopivot(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 (
lefttoright) to find the target element. The binary search continues untilleftis less than or equal toright.Inside the binary search loop, we calculate the middle index
midand comparenums[mid]with the target value. If they are equal, we returnmidas the index of the target element. Ifnums[mid]is less than the target, we updatelefttomid + 1to search in the right half. Ifnums[mid]is greater than the target, we updaterighttomid - 1to 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.