使用中位数中位数找到第k个最大元素的复杂性

时间:2012-09-22 18:53:08

标签: python algorithm median-of-medians

我正在阅读有关通过ardendertat median-of-medians算法找到数组中第k个最高元素的文章。在解释复杂性的部分中,作者似乎已经忽略了一个因素,即递归地为每个分区找到median-of-medians的成本。当然我不能通过初始支点对所有子阵列进行分区,对吧?那么这不会增加复杂性吗?

2 个答案:

答案 0 :(得分:2)

中值中值算法是为快速选择算法开发的,它与快速排序非常相似,但实际上是线性而不是O(n log n),因为它只在分区的一侧进行递归。选择问题是选择集合S中的k th 最大元素;找到中位数是特殊情况,其中k =(| S | + 1)/ 2。

算法很简单:

  • 选择一些透视值,p。

  • 将元素分为两组:S &lt; (所有元素&lt; p)和S (所有元素≥p)。< / p>

  • 递归:如果S &lt; 至少为k,则在S &lt; 中找到k th 最大元素;否则,在S 中找到(k - | S &lt; |) th 最大元素。

与quicksort一样,关键是找到透视值。我们将按如下方式进行:

  • 构造S medians ,由每组五个元素的中间人组成。

  • 通过递归调用select来找到S medians 的确切中位数。

现在,| S medians |正好是0.2 * | S |。此外,一旦我们有了支点,我们就知道max(| S &lt; |,| S )≤0.7* | S |。 [fn 1]所以这两个递归调用选择总和为0.9 * | S |。

因此,我们现在可以证明计算选择的时间与Σ0.9 i n成正比,这在n中是明显线性的。

我希望这对你来说足够清晰。


如果不明显,S medians 中的一半中位数必须至少为p(因为p是它们的中位数),并且对于那些对应于这些中位数的每组五个,三个五个元素(中位数和两个较大元素)必须至少为p。因此,这是S中50%的总元素的60%,即30%。类似的论证适用于“至多”代替“至少”,因此我们知道两个子集中较小的一个至少是S大小的30%,因此较大的子集最多为该大小的70%。

答案 1 :(得分:1)

分区数组后中位数中位数p介于0.3*n0.7*n之间。

所以在一轮之后,我们有三种可能性:

  1. p == n-k,幸运的是,第一个支点是k个最大的元素,在O(n)中找到(中位数和分区的中位数都是O(n))。
  2. p > n-k,然后第k个最大元素小于第一个数据透视图,我们需要找到第一部分的k - (n-p)个最大元素,它最多包含0.7*n个元素,因此找到k个最大元素的总成本是

    T(n) <= T(0.7*n) + C*n
    
  3. p < n-k,然后我们需要找到第二部分的第k个最大元素(在数据透视之后),该部分最多也是0.7*n个元素,所以我们再次估算

    T(n) <= T(0.7*n) + C*n
    
  4. 迭代,我们找到了

    T(n) <= T((0.7)^k * n) + C*(1 + 0.7 + ... + (0.7)^(k-1))*n
         <= T(1) + C/(1 - 0.7)*n
    

    显然是O(n)。