仅使用O(k)内存O(n)时间从给定序列中找到第k个最小元素


11

假设我们逐个读取数字的序列。如何仅使用单元存储器并在线性时间()中找到第个最小元素。我认为我们应该保存序列的前项,并在获得第个项时删除一个确定不能为第个最小元素的项,然后保存第个项。因此,我们应该有一个指标,在每个步骤中显示此不可用的术语,并且该指标应在每个步骤中快速更新。我从“ max”开始;但它无法快速更新;意味着如果我们考虑最大ķnkO (n )k k + 1 k k + 1O(k)O(n)kk+1kk+1然后在第一次删除中,我们错过了最大值,我们应该在搜索最大值,其原因时间不是线性的。也许我们应该更智能地保存前项。O(k)k(n−k)×O(k)k

我该如何解决这个问题?


1
您是否对在线算法感兴趣,或者任何算法都可以?
— Yuval Filmus

如果k=θ(n)则可以使用阶数统计算法来实现。如果k=o(n)则可以使用任何高度平衡的树来执行O(k)内存和O(nlog⁡k)时间。
— Shreesh


有线性时间就地算法,您可以在Google上搜索,但是它们有些复杂。
— Yuval Filmus

@ xavierm02不是完全相同的选择问题。因为存在内存限制约束。
— Shahab_HK

Answers:


16

创建大小为的缓冲区。从数组中读取2 k个元素。使用 线性时间选择算法对缓冲区进行分区,以使k个最小的元素排在最前面;这需要O (k )时间。现在,将数组中的另外k个项目读入缓冲区,替换缓冲区中k个最大的项目,像以前一样对缓冲区进行分区,然后重复。2k2kkO(k)kk

这需要时间和O (k )空间。O(k∗n/k)=O(n)O(k)


+1,适合要求的渐近性。话虽如此,但我不认为这比执行单个线性时间选择算法要快...除了很小时,它提供了一个有趣的视角。例如,对于k = 1,此算法将产生函数。kk=1min
— orlp

1
有时,线性时间选择算法会占用太多空间。例如,它不适用于流上下文或输入数组是不可变的。
— jbapple

这些是有效点。
— Orlp

3

您可以在内存和O (n log k )时间中做到这一点,方法是从O (k )时间中的前k个元素形成固定大小的最大堆,然后遍历数组的其余部分并推入新的元素,然后为每个元素弹出O (log k ),得到总时间O (k + n log k ) = O (n log k )。O(k)O(nlog⁡k)kO(k)O(log⁡k)O(k+nlog⁡k)O(nlog⁡k)

通过使用中位数中值选择算法,在k处选择并返回前k个元素,可以在辅助存储器和O (n )时间中进行操作。在不改变渐近性的情况下,您可以使用introselect加快平均情况。这是解决问题的规范方法。O(log⁡n)O(n)kk

现在从技术上讲和O (k )是无法比拟的。但是我认为O (log n )在实践中更好,因为考虑到没有计算机系统具有超过2 64个字节的内存,log 2 64 = 64,它实际上是恒定的。同时,k可以增长到与n一样大。O(log⁡n)O(k)O(log⁡n)264log⁡264=64kn


请注意,可以通过在有趣的时候反转堆使用的顺序,将基于堆的算法的复杂度提高到。O(n×log⁡min(k,n−k))
— xavierm02'1

@ xavierm02 = Ô (ķ )。证明:k的最坏情况是n。m i n (k ,n - k )的最坏情况是nO(min(k,n−k))O(k)knmin(k,n−k)。它们是一个常数因子内的相同,从而 ø(米我Ñ(ķ,Ñ-ķ))=Ô(ķ)。n2O(min(k,n−k))O(k)
— Orlp

@ xavierm02话虽如此,它仍然是一个不错的
— 加速器

是 O (k )但不是 O (min (k ,n - k ))。假设是。再有就是一些 Ç和一些中号,使得对于每个中号≤ ķ ≤ Ñ,我们有 ķ ≤ Ç (ñ - ķ ),这显然是错误的(因为我们可以采取 Ñ = ķ → + ∞ )。un,k=kO(k)O(min(k,n−k))CMM≤k≤nk≤C(n−k)n=k→+∞). 所以。O(min(k,n−k))⊊O(k)
— xavierm02 '01 / 01/17

@ xavierm02我不熟悉你的符号。公平地讲,我通常不太熟悉多维big- O表示法,尤其是考虑到n ,k并非无关紧要。un,kOn,k
— orlp
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.