658. 找到 K 个最接近的元素(双指针)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-k-closest-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。
示例 1:
输入: [1,2,3,4,5], k=4, x=3
输出: [1,2,3,4]
示例 2:
输入: [1,2,3,4,5], k=4, x=-1
输出: [1,2,3,4]
说明:
k 的值为正数,且总是小于给定排序数组的长度。
数组不为空,且长度不超过 104
数组里的每个元素与 x 的绝对值不超过 104
更新(2017/9/19):
这个参数 arr 已经被改变为一个整数数组(而不是整数列表)。 请重新加载代码定义以获取最新更改。
1、双指针法
思想:**
找到k个最接近x的元素,相当于从原数组arr中删除len - k个元素剩余的元素,
而删除的依据是:当x与左端元素arr[left]差值大于x与右端元素arr[right]差值时,
说明x距离右端元素更近,所以删除左端元素;反之,删除右端元素;之后用列表存储返回即可
代码
/*
1、双指针法
找到k个最接近x的元素,相当于从原数组arr中删除len - k个元素剩余的元素,
而删除的依据是:当x与左端元素arr[left]差值大于x与右端元素arr[right]差值时,
说明x距离右端元素更近,所以删除左端元素;反之,删除右端元素;之后用列表存储返回即可
*/
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
List<Integer> res = new LinkedList<>();
int len = arr.length;
int left = 0, right = len - 1;
int removNum = len - k;
while(removNum != 0){
if( (x - arr[left]) > (arr[right] - x) ){
left++;
}
else{
right--;
}
removNum--;
}
for(int i = left; i <= right; i++){
res.add(arr[i]);
}
return res;
}
}
2、二分法
思想:**
找到k个最接近x的元素,相当于从原数组arr中删除len - k个元素剩余的元素,
由于右端最多len - k个元素,所以右边界选择right = len - k;//注意右端点
而删除的依据是:当x与左端元素arr[mid]差值大于x与右端元素arr[mid + k]差值时,
说明x距离右半边元素更近,所以删除左半边元素;
反之,删除右半边元素;之后用列表存储返回即可
原理见大佬分析:
https://leetcode-cn.com/problems/find-k-closest-elements/solution/pai-chu-fa-shuang-zhi-zhen-er-fen-fa-python-dai-ma/
代码
/*
2、二分法
找到k个最接近x的元素,相当于从原数组arr中删除len - k个元素剩余的元素,
由于右端最多len - k个元素,所以右边界选择right = len - k;//注意右端点
而删除的依据是:当x与左端元素arr[mid]差值大于x与右端元素arr[mid + k]差值时,
说明x距离右半边元素更近,所以删除左半边元素;
反之,删除右半边元素;之后用列表存储返回即可
原理见大佬分析:
https://leetcode-cn.com/problems/find-k-closest-elements/solution/pai-chu-fa-shuang-zhi-zhen-er-fen-fa-python-dai-ma/
*/
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
List<Integer> res = new LinkedList<>();
int len = arr.length;
int left = 0, right = len - k;//注意右端点
while(left < right){
int mid = left + (right - left) / 2;
if( (x - arr[mid]) > (arr[mid + k] - x) ){
left = mid + 1;
}
else{
right = mid;
}
}
for(int i = left; i < left + k; i++){
res.add(arr[i]);
}
return res;
}
}