Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
题目很简单,就是多次二分查找嘛,但是写起来要稍微注意一点细节,上我的代码
package main
import (
"fmt"
)
const (
NOT_FOUND = -1
)
// 二分查找
func find_num(arr []int, num int, left_index int, right_index int) int {
mid_index := (left_index + right_index) / 2
for left_index < right_index-1 {
if num < arr[mid_index] {
right_index = mid_index
mid_index = (left_index + right_index) / 2
} else if num > arr[mid_index] {
left_index = mid_index
mid_index = (left_index + right_index) / 2
} else {
return mid_index
}
}
if num == arr[right_index] {
return right_index
} else if num == arr[left_index] {
return left_index
}
return NOT_FOUND
}
func start_end_pos(arr []int, num int) (int, int) {
length := len(arr)
left_index := 0
right_index := length - 1
one_index := find_num(arr, num, left_index, right_index)
start_index := one_index
end_index := one_index
if one_index > left_index {
pos := find_num(arr, num, left_index, one_index-1)
if pos != NOT_FOUND {
start_index = pos
}
}
if one_index+1 < right_index {
pos := find_num(arr, num, one_index+1, right_index)
if pos != NOT_FOUND {
end_index = pos
}
}
left_flag := true
right_flag := true
for left_flag || right_flag {
if start_index > left_index && left_flag {
//裁剪
if num != arr[start_index-1] {
left_flag = false
goto right
}
//查找
pos := find_num(arr, num, left_index, start_index-1)
if pos == NOT_FOUND || start_index == pos {
left_flag = false
} else {
start_index = pos
}
}
right:
if end_index+1 < right_index && right_flag {
//裁剪
if num != arr[end_index+1] {
right_flag = false
continue
}
//查找
pos := find_num(arr, num, end_index+1, right_index)
if pos == NOT_FOUND || end_index == pos {
right_flag = false
} else {
end_index = pos
}
}
}
return start_index, end_index
}
func main() {
arr := []int{3, 4, 5, 5, 5, 5, 23, 56}
start, end := start_end_pos(arr, 5)
fmt.Printf("[%d,%d]", start, end)
}
输出结果:
[2,5]