查找具有值范围的 k 个最大元素的有效算法

Posted

技术标签:

【中文标题】查找具有值范围的 k 个最大元素的有效算法【英文标题】:Efficient algorithm for finding k largest elements with range of values 【发布时间】:2015-05-04 20:23:46 【问题描述】:

假设有一个元素列表,每个元素都有一个范围,因此元素的值将位于该范围内。元素之间的范围可能重叠。确切的值未知,但可以计算出来。选择具有最高 k 值的元素的最佳算法是什么,使得精确计算的次数最少?

我有一个非常幼稚和直接的算法,但这绝对不是最优的。

    根据最大范围值对范围进行排序。 计算前 k 个值。 移除目前最大范围值小于第 k^th 个最大值的元素。 从剩余元素中,计算具有最大范围值的元素的值,并更新最高 k 列表。如果没有剩余元素,则停止。 转到3

【问题讨论】:

您的方法实际上看起来很合理。一种可能的改进可能是优化您的排序基础 - 我认为理想情况下您希望按预期值排序,而不是最大可能值。例如,如果值在minmax 之间均匀分布,则可以按(min+max)/2 排序。 您的问题有些模棱两可:您想find elements with highest k values 还是find k largest elements?将 k 替换为 5 之类的实数,然后阅读并决定您需要哪个并相应地更正问题。 我要找k个实际值最高的元素。 【参考方案1】:

这可以在不离开天真境界的情况下得到改善:

可以保证,元素 A 的最大范围小于元素 B 的最小范围也具有较低的实际值。因此,您删除所有范围最大值低于第 5 高范围最小值的元素。这会给您留下一个更小的列表:如果您的原始列表很长(即:基于磁盘),您很可能可以将其缩减为基于内存的版本。除此之外,选择运行很可能会让您看到这个子列表已经排序。 如果仍然需要,对较小的列表进行排序 (*) 现在循环类似于您的原始算法: 从列表中删除最高最大值的元素并计算它的实际值,将其排序到排序的工作列表中 将 range-max 低于此值的所有值从当前列表移动到辅助列表,保持排序 这为您提供了一个更短的工作列表,确保包含最高值 如果有足够的条目,则选择最高的 k 并完成 如果不是这样,请将辅助列表设为新的主列表并转到 (*)

【讨论】:

感谢您的回答。我喜欢第一个项目符号中提出的观点。将辅助列表保留在第二个项目符号中没有用,因为在这两种情况下,接下来要查询的元素和查询的数量都是相同的。 @user1583688 二级列表的目的还是为了保持小规模:它最大限度地减少了计算实际值所需的步骤除了 - 拆分排序列表是一种非常便宜的操作,就像用另一个列表替换列表一样

以上是关于查找具有值范围的 k 个最大元素的有效算法的主要内容,如果未能解决你的问题,请参考以下文章

算法快速选择算法 ( 数组中找第 K 大元素 )

在特定元素上查找排序数组的范围索引

计数排序是个啥?

Broken BST CodeForces - 797D

查找最大索引 j 的有效算法,使得从索引 i 到 j 的总和小于 k

排序算法之选择排序