LC 658. 找到 K 个最接近的元素 (opens new window) (opens new window)
中等
# 问题描述
给定一个 排序好 的数组 arr
,两个整数 k
和 x
,从数组中找到最靠近 x
(两数之差最小)的 k
个数。返回的结果必须要是按升序排好的。
整数 a
比整数 b
更接近 x
需要满足:
|a - x| < |b - x|
或者|a - x| == |b - x|
且a < b
示例 1:
输入:arr = [1,2,3,4,5], k = 4, x = 3
输出:[1,2,3,4]
示例 2:
输入:arr = [1,2,3,4,5], k = 4, x = -1
输出:[1,2,3,4]
提示:
1 <= k <= arr.length
1 <= arr.length <= 104
arr
按 升序 排列104 <= arr[i], x <= 104
# 排序
将数组按更接近 的规则进行排序,排序后截取前 个数,再将截取出的数据从小到大排序即可。
/**
* @param {number[]} arr
* @param {number} k
* @param {number} x
* @return {number[]}
*/
var findClosestElements = function (arr, k, x) {
return arr
.sort((a, b) => {
const d1 = Math.abs(a - x)
const d2 = Math.abs(b - x)
if (d1 !== d2) {
return d1 - d2
} else {
return a - b
}
})
.slice(0, k)
.sort((a, b) => a - b)
}
- 时间复杂度:
- 空间复杂度:
# 二分查找 + 双指针
使用二分查找找出小于等于 的最大下标 ,然后以 为右端, 为左端,向左右扩散 次,最终对数组进行截取。
/**
* @param {number[]} arr
* @param {number} k
* @param {number} x
* @return {number[]}
*/
var findClosestElements = function (arr, k, x) {
const n = arr.length
let l = 0
let r = n - 1
while (l < r) {
const mid = (l + r) >> 1
if (arr[mid] === x) {
l = mid
break
} else if (arr[mid] < x) {
l = mid + 1
} else {
r = mid
}
}
r = l--
while (k-- > 0) {
if (l < 0) {
r++
} else if (r >= n) {
l--
} else if (x - arr[l] <= arr[r] - x) {
l--
} else {
r++
}
}
return arr.slice(l + 1, r)
}
- 时间复杂度:
- 空间复杂度:
上次更新: 2023/01/31 19:48:05
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 , 转载请注明出处!