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.
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
Example 3:
Input: nums = [1], target = 0 Output: -1
Constraints:
1 <= nums.length <= 5000
-104 <= nums[i] <= 104
nums
are unique.nums
is an ascending array that is possibly rotated.-104 <= target <= 104
This problem requires finding the index of a target
element within a rotated sorted array. A rotated sorted array is a sorted array that has been rotated at some pivot point. For example, [0, 1, 2, 4, 5, 6, 7]
rotated at pivot 3 becomes [4, 5, 6, 7, 0, 1, 2]
. The challenge is to solve this efficiently, in O(log n) time complexity, which suggests a binary search approach.
A standard binary search won't work directly because the array isn't sorted globally. However, we can exploit the fact that at least one half of the array will always be sorted. This is the key insight that allows us to adapt the binary search algorithm.
The algorithm works as follows:
Initialization: Set left
to 0 and right
to nums.length - 1
.
Iteration: While left
is less than right
:
mid
index.nums[left] <= nums[mid]
:
target
falls within the range of the sorted left half (nums[left] <= target <= nums[mid]
), then search in the left half (right = mid
).left = mid + 1
).target
falls within the range of the sorted right half (nums[mid] < target <= nums[right]
), then search in the right half (left = mid + 1
).right = mid
).Termination: The loop terminates when left
and right
converge. At this point:
nums[left]
equals the target
, return left
.Time Complexity: O(log n). The binary search algorithm halves the search space in each iteration, resulting in logarithmic time complexity.
Space Complexity: O(1). The algorithm uses a constant amount of extra space.
The core logic remains consistent across different programming languages. Here are examples in Python and Java to illustrate:
Python:
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
# Check if left half is sorted
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
# Otherwise, right half is sorted
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1 # Target not found
Java:
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) return mid;
// Check if left half is sorted
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else { // Right half is sorted
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1; // Target not found
}
}
The other language examples provided in the original response follow a very similar structure, adapting the core binary search logic to handle the rotated array. The key differences are primarily in syntax and data structure handling specific to each language.