概述
我们的目标是找到一个元素在排序数组中的第一个和最后一个位置。
实验结果
Input: [1, 2, 2, 5]
Target: 2
Output: [1, 2]
Input: [1, 2, 5]
Target: 2
Output: [1, 1]
Input: []
Target: 1
Output: [-1,-1]
策略是
-
在数组中进行二进制搜索,找到左边的索引。
-
然后在数组中再做一次二进制搜索,找到右边的索引。
程序
以下是相同的程序
package main
import "fmt"
func main() {
output := searchRange([]int{1, 2, 2, 5}, 2)
fmt.Println(output)
output = searchRange([]int{1, 2, 5}, 2)
fmt.Println(output)
output = searchRange([]int{}, 1)
fmt.Println(output)
}
func searchRange(nums []int, target int) []int {
output := make([]int, 2)
output[0] = findLeftPivot(nums, 0, len(nums)-1, target, len(nums))
output[1] = findRightPivot(nums, 0, len(nums)-1, target, len(nums))
return output
}
func findLeftPivot(nums []int, start, end, target, len int) int {
if start > end {
return -1
}
if start == end && nums[start] == target {
return start
}
mid := (start + end) / 2
if (mid == 0 || nums[mid-1] < nums[mid]) && nums[mid] == target {
return mid
}
if target <= nums[mid] {
return findLeftPivot(nums, start, mid-1, target, len)
}
return findLeftPivot(nums, mid+1, end, target, len)
}
func findRightPivot(nums []int, start, end, target, len int) int {
if start > end {
return -1
}
if start == end && nums[start] == target {
return start
}
mid := (start + end) / 2
if mid+1 <= end && nums[mid] == target && nums[mid] < nums[mid+1] {
return mid
}
if (mid == len-1 || nums[mid] < nums[mid+1]) && nums[mid] == target {
return mid - 1
}
if target >= nums[mid] {
return findRightPivot(nums, mid+1, end, target, len)
}
return findRightPivot(nums, start, mid-1, target, len)
}
输出
[1 2]
[1 1]
[-1 -1]