LeetCode——658. 找到 K 个最接近的元素(双指针)

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;
    }
}


猜你喜欢

转载自blog.csdn.net/qq_34767784/article/details/107197227