Search in Rotated Sorted Array in DSA Go - Time & Space Complexity
We want to understand how fast we can find a number in a rotated sorted list.
How does the time to find the number grow as the list gets bigger?
Analyze the time complexity of the following code snippet.
func search(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right {
mid := (left + right) / 2
if nums[mid] == target {
return mid
}
if nums[left] <= nums[mid] {
if target >= nums[left] && target < nums[mid] {
right = mid - 1
} else {
left = mid + 1
}
} else {
if target > nums[mid] && target <= nums[right] {
left = mid + 1
} else {
right = mid - 1
}
}
}
return -1
}
This code searches for a target number in a rotated sorted array using a modified binary search.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for loop that halves the search range each time.
- How many times: The loop runs about log base 2 of n times, where n is the array size.
Each step cuts the search area roughly in half, so the number of steps grows slowly as the list grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 4 steps |
| 100 | About 7 steps |
| 1000 | About 10 steps |
Pattern observation: Doubling the input size adds only one more step.
Time Complexity: O(log n)
This means the search time grows slowly, even if the list becomes very large.
[X] Wrong: "Because the array is rotated, we must check every element, so it takes O(n) time."
[OK] Correct: The code cleverly uses the sorted parts to skip half the elements each time, keeping the search fast.
Understanding this search helps you show how to handle tricky sorted data efficiently, a skill many interviews value.
"What if the array was not rotated but still sorted? How would the time complexity change?"
Practice
Solution
Step 1: Understand the array structure
A rotated sorted array is originally sorted but then rotated at some pivot, splitting it into two sorted parts.Step 2: Identify the search challenge
Because of the rotation, a simple binary search cannot be applied directly as the array is not fully sorted in one sequence.Final Answer:
The array is split into two sorted parts, making direct binary search tricky -> Option DQuick Check:
Rotation splits array = search challenge [OK]
- Assuming the array is fully sorted
- Ignoring the rotation pivot
- Trying linear search only
Solution
Step 1: Check parameter types
The function should accept a slice of integers and an integer target to search for.Step 2: Check return type
The function returns an integer index of the target or -1 if not found, so return type int is correct.Final Answer:
func search(nums []int, target int) int -> Option AQuick Check:
Correct params and return type = func search(nums []int, target int) int [OK]
- Using wrong parameter types
- Returning bool instead of index
- Using string target instead of int
nums := []int{4,5,6,7,0,1,2}
target := 0
fmt.Println(search(nums, target))
func search(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right {
mid := (left + right) / 2
if nums[mid] == target {
return mid
}
if nums[left] <= nums[mid] {
if nums[left] <= target && target < nums[mid] {
right = mid - 1
} else {
left = mid + 1
}
} else {
if nums[mid] < target && target <= nums[right] {
left = mid + 1
} else {
right = mid - 1
}
}
}
return -1
}Solution
Step 1: Identify target and array
Target is 0, array is rotated sorted: [4,5,6,7,0,1,2].Step 2: Trace binary search steps
Mid starts at index 3 (value 7), target 0 is not equal. Left half [4..7] is sorted. Target 0 is not in left half, so move left to mid+1=4. Now left=4, right=6. Mid=5 (value 1). Target 0 < 1, right=mid-1=4. Now left=4, right=4. Mid=4 (value 0), found target at index 4.Final Answer:
4 -> Option CQuick Check:
Target 0 found at index 4 [OK]
- Not updating left/right correctly
- Confusing sorted half
- Returning wrong index
func search(nums []int, target int) int {
left, right := 0, len(nums)-1
for left < right {
mid := (left + right) / 2
if nums[mid] == target {
return mid
}
if nums[left] <= nums[mid] {
if nums[left] <= target && target < nums[mid] {
right = mid - 1
} else {
left = mid + 1
}
} else {
if nums[mid] < target && target <= nums[right] {
left = mid + 1
} else {
right = mid - 1
}
}
}
return -1
}Solution
Step 1: Analyze loop condition
The loop uses 'left < right', which stops when left == right, possibly missing the last element check.Step 2: Correct loop condition
Changing to 'left <= right' ensures the last element is checked, preventing missed target.Final Answer:
The loop condition should be 'left <= right' instead of 'left < right' -> Option BQuick Check:
Loop must include equal to check [OK]
- Using 'left < right' and missing last element
- Incorrect mid calculation
- Wrong comparison operators
nums := []int{2,5,6,0,0,1,2}
target := 0Solution
Step 1: Understand duplicates effect
Duplicates can cause ambiguity in deciding which half is sorted when nums[left] == nums[mid] == nums[right].Step 2: Modify search to skip duplicates
When duplicates appear at left, mid, and right, increment left and decrement right to skip duplicates and continue search.Final Answer:
Add extra checks to skip duplicates when nums[left] == nums[mid] == nums[right] -> Option AQuick Check:
Skip duplicates to avoid ambiguity [OK]
- Ignoring duplicates causing wrong half detection
- Switching to linear search unnecessarily
- Sorting array breaks problem constraints
Ready to prove it?
Pass the test and this pattern moves unknown
