Search in Rotated Sorted Array
MediumThe problem
A list of different numbers was sorted from smallest to biggest, then rotated: some numbers from the front were moved to the back. Given the rotated list and a target, return the index of the target, or -1 if it is not in the list.
- Example 1Input: nums = [4, 5, 6, 7, 0, 1, 2], target = 0Output: 4
nums[4] is 0.
- Example 2Input: nums = [4, 5, 6, 7, 0, 1, 2], target = 3Output: -1
3 is not in the list.
- Example 3Input: nums = [1], target = 0Output: -1
The only number is 1.
- 1 ≤ nums.length ≤ 100,000
- All numbers are different
- The list was sorted and then rotated 0 or more times
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
At any mid, at least one half is perfectly sorted. Can you tell which, and whether the target lives in it?
The idea
Decide which half is sorted (nums[lo] ≤ nums[mid]); if the target lies inside that sorted range go there, else go to the other half.
Target: O(log n) time
Go function shape
func search(nums []int, target int) intReference solution
Tested with go test. Try it yourself first, then compare.
// SearchRotated: target in a rotated sorted slice of distinct values, or -1.
// Step 1: find the rotation point (index of the minimum). Step 2: binary search the right half.
func SearchRotated(nums []int, target int) int {
n := len(nums)
if n == 0 {
return -1
}
// the minimum is the first element that is <= the last element
pivot := firstTrue(n, func(i int) bool { return nums[i] <= nums[n-1] })
// treat the slice as sorted with a shifted index: real = (i + pivot) % n
i := firstTrue(n, func(i int) bool { return nums[(i+pivot)%n] >= target })
if i < n && nums[(i+pivot)%n] == target {
return (i + pivot) % n
}
return -1
}
// FindMin: minimum of a rotated sorted slice of distinct values.
func FindMin(nums []int) int {
n := len(nums)
return nums[firstTrue(n, func(i int) bool { return nums[i] <= nums[n-1] })]
}