658. 找到 K 个最接近的元素
题目
给定一个 排序好 的数组 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,1,2,3,4,5], k = 4, x = -1
输出:[1,1,2,3]
提示:
1 <= k <= arr.length
1 <= arr.length <= 104
arr
按 升序 排列-104 <= arr[i], x <= 104
思路
假设n为元素个数,去掉n-k个距离最远的元素,剩下的就是最近的k个元素了。
其实代码倒真没什么好讲的,主要是这道题为什么能用双指针来解决?我目前认为,该题目有下面的特点,使得其可以使用双指针:
- 元素有序 可以不用排序,只需要根据下标就能确定元素之间的大小
- 需要确定的是一个区间 所以我们可以通过两边逼近
public List<Integer> findClosestElements(int[] arr, int k, int x) {
// 减去n-k个元素
int count = 0, l = 0, r = arr.length - 1;
while (count < arr.length - k) {
if (Math.abs(arr[l] - x) < Math.abs(arr[r] - x)) {
r--;
count++;
} else if (Math.abs(arr[l] - x) == Math.abs(arr[r] - x) && arr[l] < arr[r]) {
r--;
count++;
} else {
l++;
count++;
}
}
return Arrays.stream(arr, l, r + 1).boxed().toList();
}