[路飞]_leetcode-658-找到 K 个最接近的元素

简介: leetcode-658-找到 K 个最接近的元素

网络异常,图片无法展示
|


「这是我参与2022首次更文挑战的第35天,活动详情查看:2022首次更文挑战


[题目地址]


给定一个 排序好 的数组 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升序 排列
  • -104 <= arr[i], x <= 104


解题思路


本题要求我们找到 k 个最接近目标值的元素,因为元素数量是给定的 k 个,而且输入数组是按升序排列的,所以我们可以初始化一个滑动窗口,长度为 k,计算窗口中每个元素与目标值 x 的差值和,然后扫描从头到尾移动这个窗口,找到差值和最小的窗口,则窗口中的元素就是我们要找的 k 个数。


因为输入数组是有序的,所以当窗口下一次移动的差值和大于当前窗口的差值和,则后续的窗口范围内的差值和都会大于当前窗口的差值和,所以此时可以停止移动,返回当前窗口中的元素。


又因为根据示例1可知,当两个窗口中元素的差值和相等的时候,优先选择前面的窗口,所以我们需要从数组末尾确定窗口,然后向前移动。


代码实现


var findClosestElements = function(arr, k, x) {
  // 初始化窗口的左右边界下标
  let r = arr.length-1,l = r-k+1,
  // 初始化窗口内元素和目标值的差值
  diff = 0;
  // 计算窗口内元素和目标值的差值
  for(let i = r;i>=l;i--) diff += Math.abs(arr[i]-x)
  // 当窗口左边界没有到达下标 0 时,向左移动窗口
  while(l>0){
    // 计算窗口下次移动后的差值和
    const nextDiff = diff-Math.abs(arr[r]-x)+Math.abs(arr[l-1]-x)
    // 如果下次移动后窗口的差值和小于等于当前窗口的差值和
    if(nextDiff<=diff){
      // 移动窗口
      l--;
      r--;
      // 更新当前窗口的差值和
      diff = nextDiff;
    }
    // 否则说明找到了差值和最小的窗口,返回窗口中的元素
    else return arr.slice(l,l+k)
  }
  // 如果可以一直移动到数组最左侧,则说明最左侧的窗口是差值最小的窗口,返回该窗口中的元素
  return arr.slice(l,l+k)
}
复制代码


至此我们就完成了 leetcode-658-找到 K 个最接近的元素


如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻

相关文章
|
22天前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
31 1
|
28天前
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
30 0
|
29天前
【LeetCode 06】203.移除链表元素
【LeetCode 06】203.移除链表元素
28 0
|
29天前
【LeetCode-每日一题】移除元素
【LeetCode-每日一题】移除元素
30 0
|
3月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
3月前
|
算法
LeetCode第16题最接近的三数之和
该文章介绍了 LeetCode 第 16 题最接近的三数之和的解法,与第 15 题类似,通过双指针法减少循环次数,根据差值的绝对值来更新最接近的和,并总结了双指针可减少循环次数的要点。
|
3月前
|
算法 索引
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
这篇文章介绍了LeetCode第34题"在排序数组中查找元素的第一个和最后一个位置"的解题方法,通过使用双指针法从数组两端向中间同时查找目标值,有效地找到了目标值的首次和最后一次出现的索引位置。
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer II 082. 含有重复元素集合的组合
解决LeetCode平台《剑指 Offer II 082. 含有重复元素集合的组合》题目的Python代码实现,通过深度优先搜索算法找出所有和为特定目标值的数字组合,并在搜索过程中通过排序和跳过重复元素来避免解集中出现重复组合。
40 2
|
3月前
|
Python
【Leetcode刷题Python】16. 最接近的三数之和
解决LeetCode "最接近的三数之和" 问题的Python实现,通过排序和双指针法,记录并更新与目标值最接近的三数之和。
33 1
|
3月前
|
算法
LeetCode第27题移除元素
这篇文章介绍了LeetCode第27题"移除元素"的解题方法,通过使用双指针技巧,有效移除数组中特定值的元素并返回新数组的长度。