找到 K 个最接近的元素

113 阅读1分钟

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

658. 找到 K 个最接近的元素 - 力扣(LeetCode)

给定一个 排序好 的数组 arr ,两个整数 kx ,从数组中找到最靠近 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 按 升序 排列
  • -10^4 <= arr[i], x <= 10^4

解题

/**
 * @param {number[]} arr
 * @param {number} k
 * @param {number} x
 * @return {number[]}
 */
var findClosestElements = function (arr, k, x) {
  if (k >= arr.length) {
    return arr;
  }
  const bf = () => {
    let left = 0;
    let right = arr.length - 1;
    while (left <= right) {
      let mid = (left + right) >> 1;
      if (arr[mid] === x) {
        return mid;
      } else if (arr[mid] > x) {
        right = mid - 1;
      } else {
        left = mid + 1;
      }
    }
    return left;
  };
  let j = bf();
  let i = j - 1;
  const x2 = x * 2;
  while (j - i < k + 1) {
    if (i < 0) {
      j = i + k + 1;
    } else if (j >= arr.length) {
      i = j - (k + 1);
    } else {
      const diff = arr[j] + arr[i] - x2;
      if (diff >= 0) i--;
      else j++;
    }
  }
  return arr.slice(i + 1, j);
};