每日算法系列【LeetCode 658】找到 K 个最接近的元素
题目描述
给定一个排序好的数组,两个整数 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 个最接近的元素相关推荐
- leetcode 658. 找到 K 个最接近的元素
leetcode 658. 找到 K 个最接近的元素 题目描述: 给定一个排序好的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排 ...
- LeetCode——658. 找到 K 个最接近的元素(双指针)
文章目录 658. 找到 K 个最接近的元素(双指针) 题目 1.双指针法 思想:** 代码 2.二分法 思想:** 代码 658. 找到 K 个最接近的元素(双指针) 来源:力扣(LeetCode) ...
- Java实现 LeetCode 658 找到 K 个最接近的元素(暴力)
658. 找到 K 个最接近的元素 给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的.如果有两个数与 x 的差值一样,优先 ...
- LeetCode 658. 找到 K 个最接近的元素(二分查找)
1. 题目 给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的.如果有两个数与 x 的差值一样,优先选择数值较小的那个数. ...
- LeetCode 每日一题——658. 找到 K 个最接近的元素
1.题目描述 658. 找到 K 个最接近的元素 给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的. 整数 ...
- 【LeetCode通关全记录】658. 找到 K 个最接近的元素
[LeetCode通关全记录]658. 找到 K 个最接近的元素 题目地址
- 【658. 找到 K 个最接近的元素】
来源:力扣(LeetCode) 描述: 给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的. 整数 a ...
- 658. 找到 K 个最接近的元素
给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要是按升序排好的. 整数 a 比整数 b 更接近 x 需要满足: |a - ...
- leetcode 658. Find K Closest Elements | 658. 找到 K 个最接近的元素(二分查找+双指针)
题目 https://leetcode.com/problems/find-k-closest-elements/ 题解 在arr中找到第一个小于等于x的位置mid,然后再根据题意,用双指针分别向左. ...
- 【LeetCode Python实现】658. 找到 K 个最接近的元素(中等)
文章目录 题目描述 示例 1: 示例 2: 提示: 参考代码 题目描述 给定一个 排序好 的数组 arr ,两个整数 k 和 x ,从数组中找到最靠近 x(两数之差最小)的 k 个数.返回的结果必须要 ...
最新文章
- 学习java技术有前途吗
- 三维重建缺数据集?来看看Facebook最新发布的CO3D
- SAP QM 不常用功能点之 Physical-Sample Record
- Qt全局热键(windows篇)
- 职称计算机Word2003是考什么,2017年职称计算机考试word2003考点
- Spring(3)---spring IOC实例
- Safari/Chrome浏览器打不开淘宝/天猫网页怎么办?
- 陈玉琴老师的中医理学
- 《GPU编程与CG语言之阳春白雪下里巴人》 读书笔记1
- 计算机磁盘文件怎么加密,win10怎样对电脑硬盘文件进行加密 windows10给电脑硬盘文件加密教程...
- PiFlow 朱小杰:科学家更爱开源 | Gitee 封面人物第 19 期
- 携创教育:2022学历改革解读系列|提升学历、迫在眉睫
- 房产管理系统CAD图形管理应用有哪些?
- QuantLib 金融计算——收益率曲线之构建曲线(1)
- 国产云桌面还需跨过的坎
- java 获得系统字符集_Java - 获取系统字符集编码
- 学习Linux的第五课时
- 营养学基础知识计算机,计算机软件技术基础知识点储备(32页)-原创力文档
- LeetCode 234.回文联表 Java
- 使用internal(com.android.internal)和hidden(@hide)APIs