题目描述

给定一个排序好的数组,两个整数 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 的值为正数,且总是小于给定排序数组的长度
  • 数组不为空,且长度不超过 10^4
  • 数组里的每个元素与 x 的绝对值不超过 10^4

题解

滑动窗口

这题要找离 最近的 个元素,又因为数组是排好序的,所以离 最远的元素一定在数组两端。

那么我们只需要用两个指针,一个指针 指着第一个元素,一个指针 指着最后一个元素。如果 ,那就说明窗口中元素个数大于 ,那么就要删除一个元素。删除哪个呢?就看 谁离 更远,就删除谁。如果一样远,就删除大的元素 。就这样删到窗口中只剩 个元素为止。

这个方法时间复杂度是

二分+滑动窗口

如果 太大,那么仅仅靠滑动窗口显然不行。注意观察答案所在的窗口可以发现,这个长度为 的窗口一定是靠近 的,也就是 要么在窗口前一个位置,要么在窗口后一个位置,要么在窗口中间某个位置。 和窗口中间绝对不可能有其他的数组元素。

那么我们可以二分找到第一个比 大的元素(找第一个比它小的元素也行),然后左右各伸展出 的长度,最终答案窗口一定就在这个范围之内。然后继续使用上面的滑动窗口来求解。

这个方法时间复杂度缩减到了

二分

如果 太大,那么上面的方法又没有意义了,还是会退化到

上面两个方法都是先把窗口范围定到某一个区间里,然后一点一点的缩小窗口大小,最终得到答案的。那么能否直接判断出长度为 的答案窗口位置在哪里呢?

按照上面的思路,长度为 的窗口一定是通过长度为 的窗口删除首尾之一元素得到的。那么我们观察某一个特定的长度为 的窗口 ,如果 距离比 更远的话,那就要删除 ,同时说明 以及它左边的所有元素都不可能是答案窗口的左边界。反之如果 距离小于等于 的距离,那么就要删除 了,同时说明 右边的元素都不可能是答案窗口的左边界。

综上,我们可以用二分直接寻找答案窗口的左边界。这样时间复杂度就降到了

代码

滑动窗口(c++)

        class Solution {public:vector<int> findClosestElements(vector<int>& arr, int k, int x) {int n = arr.size();int l = 0, r = n-1;while (r-l >= k) {if (x-arr[l] <= arr[r]-x) r--;else l++;}vector<int> res(k);copy(arr.begin()+l, arr.begin()+l+k, res.begin());return res;}
};

二分+滑动窗口(c++)

        class Solution {public:vector<int> findClosestElements(vector<int>& arr, int k, int x) {int n = arr.size();int l = 0, r = n-1;while (l < r) {int m = (l + r) / 2;if (arr[m] < x) l = m + 1;else r = m;}r = min(n-1, l+k-1);l = max(0, l-k);while (r-l >= k) {if (x-arr[l] <= arr[r]-x) r--;else l++;}vector<int> res(k);copy(arr.begin()+l, arr.begin()+l+k, res.begin());return res;}
};

二分(c++)

        class Solution {public:vector<int> findClosestElements(vector<int>& arr, int k, int x) {int n = arr.size();int l = 0, r = n-k;while (l < r) {int m = (l + r) / 2;if (x-arr[m] > arr[m+k]-x) l = m + 1;else r = m;}vector<int> res(k);copy(arr.begin()+l, arr.begin()+l+k, res.begin());return res;}
};

滑动窗口(python)

        class Solution:def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:n = len(arr)l, r = 0, n-1while r-l >= k:if x-arr[l] <= arr[r]-x:r -= 1else:l += 1return arr[l:l+k]

二分+滑动窗口(python)

        class Solution:def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:n = len(arr)l, r = 0, n-1while l < r:m = (l + r) // 2if arr[m] < x:l = m + 1else:r = mr = min(n-1, l+k-1)l = max(0, l-k)while r-l >= k:if x-arr[l] <= arr[r]-x:r -= 1else:l += 1return arr[l:l+k]

二分(python)

        class Solution:def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:n = len(arr)l, r = 0, n-kwhile l < r:m = (l + r) // 2if x-arr[m] > arr[m+k]-x:l = m + 1else:r = mreturn arr[l:l+k]

每日算法系列【LeetCode 658】找到 K 个最接近的元素相关推荐

  1. leetcode 658. 找到 K 个最接近的元素

    leetcode 658. 找到 K 个最接近的元素 题目描述: 给定一个排序好的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排 ...

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

    文章目录 658. 找到 K 个最接近的元素(双指针) 题目 1.双指针法 思想:** 代码 2.二分法 思想:** 代码 658. 找到 K 个最接近的元素(双指针) 来源:力扣(LeetCode) ...

  3. Java实现 LeetCode 658 找到 K 个最接近的元素(暴力)

    658. 找到 K 个最接近的元素 给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的.如果有两个数与 x 的差值一样,优先 ...

  4. LeetCode 658. 找到 K 个最接近的元素(二分查找)

    1. 题目 给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的.如果有两个数与 x 的差值一样,优先选择数值较小的那个数. ...

  5. LeetCode 每日一题——658. 找到 K 个最接近的元素

    1.题目描述 658. 找到 K 个最接近的元素 给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的. 整数 ...

  6. 【LeetCode通关全记录】658. 找到 K 个最接近的元素

    [LeetCode通关全记录]658. 找到 K 个最接近的元素 题目地址

  7. 【658. 找到 K 个最接近的元素】

    来源:力扣(LeetCode) 描述:    给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的. 整数 a ...

  8. 658. 找到 K 个最接近的元素

    给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的. 整数 a 比整数 b 更接近 x 需要满足: |a - ...

  9. leetcode 658. Find K Closest Elements | 658. 找到 K 个最接近的元素(二分查找+双指针)

    题目 https://leetcode.com/problems/find-k-closest-elements/ 题解 在arr中找到第一个小于等于x的位置mid,然后再根据题意,用双指针分别向左. ...

  10. 【LeetCode Python实现】658. 找到 K 个最接近的元素(中等)

    文章目录 题目描述 示例 1: 示例 2: 提示: 参考代码 题目描述 给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要 ...

最新文章

  1. 学习java技术有前途吗
  2. 三维重建缺数据集?来看看Facebook最新发布的CO3D
  3. SAP QM 不常用功能点之 Physical-Sample Record
  4. Qt全局热键(windows篇)
  5. 职称计算机Word2003是考什么,2017年职称计算机考试word2003考点
  6. Spring(3)---spring IOC实例
  7. Safari/Chrome浏览器打不开淘宝/天猫网页怎么办?
  8. 陈玉琴老师的中医理学
  9. 《GPU编程与CG语言之阳春白雪下里巴人》 读书笔记1
  10. 计算机磁盘文件怎么加密,win10怎样对电脑硬盘文件进行加密 windows10给电脑硬盘文件加密教程...
  11. PiFlow 朱小杰:科学家更爱开源 | Gitee 封面人物第 19 期
  12. 携创教育:2022学历改革解读系列|提升学历、迫在眉睫
  13. 房产管理系统CAD图形管理应用有哪些?
  14. QuantLib 金融计算——收益率曲线之构建曲线(1)
  15. 国产云桌面还需跨过的坎
  16. java 获得系统字符集_Java - 获取系统字符集编码
  17. 学习Linux的第五课时
  18. 营养学基础知识计算机,计算机软件技术基础知识点储备(32页)-原创力文档
  19. LeetCode 234.回文联表 Java
  20. 使用internal(com.android.internal)和hidden(@hide)APIs

热门文章

  1. 完全掌握AS中点(.)语法的应用
  2. 【Rollo的Python之路】比较运算符
  3. mysql 的命令行操作
  4. linux 环境变量和shell变量
  5. 使用 Capistrano 和写作 Ruby 迭代边缘部署
  6. LoadRunner去除事物中的程序的执行时间
  7. SQL Server 中添加表注释
  8. 关于MDI窗体的那些问题
  9. AjaxControltoolkit学习笔记—Animation使用详解
  10. GoogleTest测试框架介绍(一)