Leetcode 658. 找到k个最接近的元素
1. 问题描述
2. 思路
按照递增序列,找到x应该插入的位置index。以此为中心,向两侧扩展长度为k的空间,该空间内的元素就是我们想要的元素。
- 1 二分查找,找到满足
<= x
的元素的最大下标index - 2 以index为中心,令
i = index, j = index + 1
, - 3 向两侧扩展,循环k次
- 3.1 如果i >= 0,且 j <= len(arr) - 1
- 3.1.1 如果arr[i]更接近x,向左移动i
- 3.1.2 如果arr[j]更接近x,向右移动j
- 3.2 如果i < 0,向右移动 j
- 3.3 如果j > len(arr) - 1,向左移动 i
- 3.1 如果i >= 0,且 j <= len(arr) - 1
3. 代码
3.1 第一次运行成功
func findClosestElements(arr []int, k int, x int) []int {
var res []int
index := binarySearch(arr, x)
// fmt.Printf("index == %v\n", index)
i, j := index, index + 1
for k > 0 {
if i >= 0 && j <= len(arr) - 1 {
if abs(arr[i], x) <= abs(arr[j], x) {
res = append(res, arr[i])
i--
} else {
res = append(res, arr[j])
j++
}
} else if i < 0 {
res = append(res, arr[j])
j++
} else if j > len(arr) - 1 {
res = append(res, arr[i])
i--
}
k--
}
sort.Ints(res)
return res
}
func binarySearch(arr []int, target int) int {
left, right := 0, len(arr) - 1
for left <= right {
mid := left + (right - left) / 2
if arr[mid] == target {
return mid
} else if arr[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return right
}
func abs(a, b int) int {
m := a - b
if m < 0 {
m = -m
}
return m
}
3.2 第二次运行成功
func findClosestElements(arr []int, k int, x int) []int {
index := binarySearch(arr, x)
i, j := index, index + 1
for k > 0 {
if i >= 0 && j <= len(arr) - 1 {
if abs(arr[i], x) <= abs(arr[j], x) {
i--
} else {
j++
}
} else if i < 0 {
j++
} else if j > len(arr) - 1 {
i--
}
k--
}
return arr[i+1:j]
}
func binarySearch(arr []int, target int) int {
left, right := 0, len(arr) - 1
for left <= right {
mid := left + (right - left) / 2
if arr[mid] == target {
return mid
} else if arr[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return right
}
func abs(a, b int) int {
m := a - b
if m < 0 {
m = -m
}
return m
}