当前位置: 首页 > 面试题库 >

查找与给定数字最接近的k个数字

叶桐
2023-03-14
问题内容

说我有一个清单[1,2,3,4,5,6,7]。我想找到3个最接近的数字,例如6.5。然后返回的值将是[5,6,7]

在python中找到一个最接近的数字并不是那么棘手,可以使用

min(myList, key=lambda x:abs(x-myNumber))

但是我试图不绕这个循环找到k个最接近的数字。有pythonic方法可以完成上述任务吗?


问题答案:

简短的答案


heapq.nsmallest()

函数将整齐,有效地做到这一点:

>>> from heapq import nsmallest
>>> s = [1,2,3,4,5,6,7]
>>> nsmallest(3, s, key=lambda x: abs(x-6.5))
[6, 7, 5]

本质上是这样说的:“给我三个与 6.5 绝对差值最小的输入值”。

算法及其运行时间

用于 nsmallest 的算法对 数据 进行一次传递,随时在内存中保留不超过 n个
最佳值(这意味着它可与任何输入迭代器一起使用,具有缓存效率和空间效率)。

该算法仅在找到新的“最佳”值时才向堆中添加新值。因此,它使进行比较的次数最小化。例如,如果要从1,000,000个随机输入中寻找100个最佳值,则通常进行的比较少于1,008,000(与使用
min()
查找单个最佳值相比,比较大约多0.8%)。

主要功能
分钟()nsmallest() ,和 排序()
所有保证该键功能在输入可迭代称为每次值一次。这意味着该技术对于n值最近的问题的更复杂和有趣的示例(即听起来最相似,最接近的颜色,最小的差异,最少的基因突变,欧几里得距离等)将非常有效。

无论 nsmallest()排序() 将返回一个列表等级排序由贴近(联系结算由值是第一次看到)。

对于那些感兴趣的人,这里和这里都存在对比较预期数量的分析。快速总结:

  • 随机输入的平均大小写: n + k * (log(k, 2) * log(n/k) + log(k, 2) + log(n/k))
  • 递增输入的最佳情况: n + k * log(k, 2)
  • 输入下降的最坏情况: n * log(k, 2)

优化重复查找

@Phylliida在评论中询问如何针对起点不同的重复查找进行优化。关键是对数据进行预排序,然后使用二等分法找到一个小的搜索段的中心:

from bisect import bisect

def k_nearest(k, center, sorted_data):
    'Return *k* members of *sorted_data* nearest to *center*'
    i = bisect(sorted_data, center)
    segment = sorted_data[max(i-k, 0) : i+k]
    return nsmallest(k, segment, key=lambda x: abs(x - center))

例如:

>>> s.sort()
>>> k_nearest(3, 6.5, s)
[6, 7, 5]
>>> k_nearest(3, 0.5, s)
[1, 2, 3]
>>> k_nearest(3, 4.5, s)    
[4, 5, 3]
>>> k_nearest(3, 5.0, s)
[5, 4, 6]

这两个 对开()nsmallest() 排序的数据占据优势。前者运行 O(log2 k) 时间,而后者运行 O(n) 时间。



 类似资料:
  • 我知道这是一个背包问题,其中权重和值相等,但我认为我在编码逻辑上犯了一个错误,因为即使对于数组中元素的数量(N)为50并且所需的最大总和(M)4500。 为了澄清这个问题,我们得到了一个由N个正整数和一个正整数M组成的数组。数组元素只能使用一次。我们必须找到这个数组的子集(不一定是连续的),使得总和最接近M,但不超过它。 这是我使用动态编程的尝试: 那么在我的代码中是否有任何可能的优化可以帮助我降

  • 我有一个非常简单的二叉树 我实现了一个函数来查找树中离目标最近的数字(19): 结果显然应该是22,但我得到了8。令人惊讶的是,当我打印所有以下“最接近”的数字时,函数似乎工作正常:它打印:8、14、22。但为什么它不返回最新的clostest数字:22?

  • 我遇到了以下leetcode问题,我对一些人用来解决它的方法有一个问题。问题是:给定一个非空二叉查找树和一个目标值,在BST中找到最接近目标的k个值。 注意:给定的目标值是浮点。 您可以假设k始终有效,即:k≤总节点。 保证BST中只有一组最接近目标的唯一k值。 所以,有些人所做的是,他们在保持k大小的最近元素队列的同时,按顺序遍历。在顺序遍历过程中,如果发现某个元素比队列中的第一个节点更接近目标

  • 给定一个未排序的数组,我试图找到最接近数组中位数的 K 个元素。我在线性运行时间内找不到解决方案。 这里的中位数是6。 答案是2,3,4,5,6。 任何帮助或提示将不胜感激。

  • 问题内容: 我希望能够在数字数组中找到最接近的较小值。例如,如果我有: 我正在寻找小于以下值的最接近值: 该函数将返回: 另外,如果我传递的数字大于数组中的最大值,则它应返回最大值。如果我传递的数字小于最小值,则应返回nil。 我尝试使用数组上的函数执行此操作,但是单独执行此操作不会产生我想要的结果,因为我需要这样的东西: 但不幸的是,这是无效的。有什么建议?我知道可以使用while循环轻松完成此

  • 我正在尝试自动查找一个数字与另一个数字的最接近因子; 示例: 700到30的最接近因子是28(30不等于700,但28等于700)。 一个显而易见的解决方案就是得到700的所有因子,并做一个简单的距离计算,找到离30最近的因子,但这似乎是低效的。 另一种解决方案是找到所有基本质因数,例如: 将这些数字相乘得到所有的组合,从而找到最接近的。 我正在尝试对其进行编程,使其自动化。有更好的解决方案吗?