找到 K 个最接近的元素

119 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

说在前面

🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是处于什么原因,算法学习需要持续保持,今天让我们一起来看看这一道题目————找到 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,2,3,4,5], k = 4, x = -1
输出:[1,2,3,4]

提示:

  • 1 <= k <= arr.length
  • 1 <= arr.length <= 10^4
  • arr 按 升序 排列
  • -10^4 <= arr[i], x <= 10^4

思路分析

首先我们要先理解一下题意,第一遍可能不太好理解,读多几遍后我们发现其实题目很简单,就是要求我们从数组arr中找到与x的差的绝对值最小的k个数,两数与x的差值的绝对值相等时,我们优先选择数值较小的,即题目所说的:

整数 a 比整数 b 更接近 x 需要满足:

  • |a - x| < |b - x| 或者
  • |a - x| == |b - x| 且 a < b

我们可以通过自定义排序方法来对数组进行重新排序,将数组按照题目要求的规则进行重新排序,以下方法是按照自定义的规则进行排序,传入两个参数a、b :

  • (1) 当返回值为负数时(即a < b),排序后数组中a的值排在b的前面,升序排序;
  • (2) 当返回值为正数时(即a > b),排序后数组中a的值排在b的后面,降序排序;
  • (3) 当返回值为0时(即a = b),顺序无变化;

使用sort函数的自定义排序方法可以实现很多种有趣的排序,如:

  • 1、从大大小排序
let arr = [1,2,3,4,5];
arr.sort((a,b)=>{
    return b - a;
});
console.log(arr); // [ 5, 4, 3, 2, 1 ]
  • 2、偶数在前奇数在后且从小到大排序
let arr = [56,58,60,111,112,113,114,115,116,117,118,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
arr.sort((a,b)=>{
    return a % 2 == 0 ? (b % 2 == 0 ? (a - b) : -1) : (b % 2 == 1 ? (a - b) : 1);
});
console.log(arr);
/*
 [
    2,   4,   6,   8,  10,  12,  14,  16, 18,
   20,  56,  58,  60, 112, 114, 116, 118,  1,
    3,   5,   7,   9,  11,  13,  15,  17, 19,
  111, 113, 115, 117
]
*/
  • 3、按绝对值大小排序
let arr = [-1,-2,-3,-4,0,1,2,3,4,56,7,8,9,7,1,2];
arr.sort((a,b)=>{
    return Math.abs(a) - Math.abs(b);
});
console.log(arr);
/*
[
  0, -1, 1,  1, -2, 2,
  2, -3, 3, -4,  4, 7,
  7,  8, 9, 56
]
*/

那么这道题目也可以使用自定义排序方法来进行排序,排完序之后我们只需要去其前 k 个元素即可得到答案,具体排序规则如下:

arr.sort((a, b) => {
    if (Math.abs(a - x) !== Math.abs(b - x)) {
        return Math.abs(a - x) - Math.abs(b - x);
    } else {
        return a - b;
    }
})

完整代码如下:

AC代码

/**
 * @param {number[]} arr
 * @param {number} k
 * @param {number} x
 * @return {number[]}
 */
 var findClosestElements = function(arr, k, x) {
    return arr.sort((a, b) => {
        if (Math.abs(a - x) !== Math.abs(b - x)) {
            return Math.abs(a - x) - Math.abs(b - x);
        } else {
            return a - b;
        }
    }).slice(0, k).sort((a, b) => a - b);
};

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。