题目:
给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。
整数 a 比整数 b 更接近 x 需要满足:
|a - x| < |b - x|或者|a - x| == |b - x|且a < b
算法:
func findClosestElements(arr []int, k int, x int) []int {
left, right := 0, len(arr) - 1
ans := make([]int, 0)
// 先找到最接近x的数的位置index
for left < right {
mid := left + (right - left) / 2
if arr[mid] < x {
left = mid + 1
} else {
right = mid
}
}
// 最终left,right的位置index是大于等于x的位置
// 将left,right定位到离x最小的位置
if arr[left] != x && left > 0 && abs(arr[left - 1], x) < abs(arr[left], x) {
left --
right = left
}
for right - left < k {
// fmt.Println(left - 1,right + 1,"val:",arr[left:right+1], "abs:", abs(arr[left-1],x), abs(arr[right+1],x))
if lessDistance(arr, left - 1, right + 1, x) {
left --
} else {
right ++
}
}
if lessDistance(arr, left, right, x) {
right --
} else {
left ++
}
for left <= right {
ans = append(ans, arr[left])
left ++
}
return ans
}
func abs(a, b int) int {
if a > b {
return a - b
}
return b - a
}
// arr[left]到val比arr[right]到val更近
func lessDistance(arr []int, left, right, val int) bool {
if left < 0 {
return false
}
if right > len(arr) - 1 {
return true
}
abs1 := abs(arr[left], val)
abs2 := abs(arr[right], val)
if abs1 == abs2 {
return left < right
}
return abs1 < abs2
}