我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第5篇文章,点击查看活动详情
本次刷题日记的第 106 篇,力扣题为:658. 找到 K 个最接近的元素
一、题目描述:
继续来刷每日一题,找到 K 个最接近的元素,看需要我们如何去实现
二、这道题考察了什么思想?你的思路是什么?
题目的意思很明确,
- 第一给出我们一个 arr 排序数组,里面都是整型数字
- 第二给出了 x 的值,需要我们在数组 arr 中找到和 x 差值绝对值最小的 k 个数字,且这 k 数字需要以升序排序好,返回结果
分析
如何去思考这个题目呢?咱们直接从需求出发
题目既然说了 arr 数组是排序好的,又要我们找到数组中和 x 差值要尽可能的小,那么咱们必然要找到 arr 数中和 x 差值绝对值最小的一个数对应的位置
这个时候,问题就来到如何查找 arr 数组中与 x 差值绝对值最小的数字了
- 简单的可以使用遍历的方式来找到
- 也可以使用二分查找的方式来查找最接近 x 的数字和其索引
另外,找到这个数字和其对应的索引之后,我们接下来就需要考虑,如何在这个基础上再找 k 个数字(包含当前找到的) 也尽可能的满足和 x 的差值的绝对值最小
那么,我们可以这样来找
咱们在数组中找到离 x 最近的数字 3 ,然后在向两边找,如果左边的值如 left 和 x 的差值的绝对值 小于 右边 right 和 x 差值的绝对值,则左边继续找,否者右边继续找
当然如果咱们找到左边的边界,或者右边的边界的时候,就往对方的方向去找,直到找到 k 个数即可
最终返回 left 到 right 中间的数字即是我们要找的 k 个数字
那么接下来就来手撸代码吧
三、编码
根据上述逻辑和分析,我们就可以翻译成如下代码
编码如下:
func findClosestElements(arr []int, k int, x int) []int {
// 找到 x 所在的 arr 中最近的一个索引
right := sort.SearchInts(arr, x)
left := right-1
for ;k>0; k-- {
if left < 0{
right++
}else if right >= len(arr) || x - arr[left] <= arr[right] - x{
left--
}else{
right++
}
}
return arr[left+1:right]
}
四、总结:
本次咱们这种实现的方式是,先通过二分法去查找离 x 最近的数,然后再遍历 k 次,因此咱们的时间复杂度是 O(logn + k)
咱们没有引入额外其他数量级的空间消耗,因此时间复杂度是 O(1)
原题地址:658. 找到 K 个最接近的元素
今天就到这里,学习所得,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
暂时无法在文档外展示此内容