Search in Rotated Sorted Array medium
Problem Statement
Suppose an array of length n
sorted in ascending order is rotated between 1 and n
times. For example, the array nums = [0,1,2,4,5,6,7]
might become:
[4,5,6,7,0,1,2]
if it was rotated 4 times.[0,1,2,4,5,6,7]
if it was rotated 0 times.
You are given a target value target
to search for in this rotated array nums
. If target
exists, then return its index; otherwise, return -1
.
You must write an optimized algorithm with O(log n)
runtime complexity.
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0 Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3 Output: -1
Steps and Explanation
The key to solving this problem efficiently is using binary search. However, a standard binary search won't work because the array is rotated. We need to adapt the binary search to handle the rotation.
Here's the strategy:
-
Find the Pivot: The pivot is the smallest element in the rotated array. It's the point where the array "breaks" from sorted order. We can find this using a modified binary search. Observe that the pivot element will always be smaller than the element at the end of the array.
-
Binary Search in the Correct Half: Once we find the pivot, we know which half of the array is sorted. We can then perform a standard binary search within the correct sorted half to find the target.
Detailed Algorithm:
- Initialize
left
andright
pointers:left = 0
,right = nums.size() - 1
. - Find the Pivot (modified binary search):
- While
left < right
:mid = (left + right) / 2
- If
nums[mid] > nums[right]
: // Pivot is in the right halfleft = mid + 1
- Else: // Pivot is in the left half or
mid
is the pivotright = mid
- While
- Determine which half is sorted:
- After the loop,
left
will point to the pivot. The sorted half will be eithernums[0...left-1]
ornums[left...nums.size()-1]
.
- After the loop,
- Perform Binary Search:
- If
target
falls within the sorted range, perform a standard binary search in that range. - Otherwise, the target is not in the array, return
-1
.
- If
Code (C++)
#include <vector>
class Solution {
public:
int search(std::vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
// Find the pivot
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[right]) {
left = mid + 1;
} else {
right = mid;
}
}
// Determine which half to search
int pivot = left;
if (target >= nums[0] && target < nums[pivot]) {
left = 0;
right = pivot - 1;
} else {
left = pivot;
right = nums.size() - 1;
}
// Binary search in the correct half
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // Target not found
}
};
Complexity
- Time Complexity: O(log n). Both the pivot finding and the binary search steps have logarithmic time complexity.
- Space Complexity: O(1). The algorithm uses a constant amount of extra space.