【问题标题】:Sorting in O(n) time?在 O(n) 时间内排序?
【发布时间】:2013-11-01 06:10:42
【问题描述】:

我被这个问题困住了(2 周)。知道如何处理它吗?。

令 L 是 n 个不同整数的列表,假设 L 的 x 的元素在 [1,750] 范围内。设计一个线性排序算法对L的元素进行排序

我已经尝试过插入排序。但我不确定我的方法是否正确:

Construct an array of bits. Initialize them to zero.
Read the input, for each value you see set the respective bit in the array to 1.
Scan the array, for each bit set, output the respective value.

复杂度 => O(2n) = O(n)

【问题讨论】:

  • 嗯,你的方法是什么?
  • @ChristianTernus 他说他尝试使用插入排序,fwiw。
  • 是的,但这与显示代码或至少是伪代码不同。
  • 在 wc,我认为不可能在 O(n) 处排序。
  • 我编辑了问题

标签: algorithm sorting time-complexity


【解决方案1】:

尝试基数排序 - http://en.wikipedia.org/wiki/Radix_sort

如果您将给定的 750 视为常数,则它的排序为 O(n)。

基于比较的排序不能以小于 O(nlogn) 的方式排序,但如果值的数量以 D 为界,则可以以 O(D*n) 进行排序,如果将 D 视为常数,则可以以 O(n) 进行排序.

【讨论】:

  • 当然是定理。任何比较算法都是 O(n log n)。你能给我一个更广泛的解释吗?
  • 解释基数或基于比较的排序复杂性?
【解决方案2】:

我不会给出完整的方法,但这里有一个应该有所帮助的观察结果。

您已经知道这些数字严格在[1, 750] 范围内。算出每个数字在线性时间内有多少并不是特别困难。

一旦你有了这些信息,你怎么能取回排序的列表(再次,在线性时间)?


至于您给出的方法,这不是插入排序,它更像是桶排序或计数排序(这是我试图暗示的)。我看到的一件事是,如果数组可以包含重复项,您的方法将不起作用。如果你被告知没有,那么你很高兴。否则,您将需要修改您必须处理的内容。

【讨论】:

  • 注意,如果范围特别大,我不会推荐类似的方法。
【解决方案3】:

您可以使用计数排序。对输入进行哈希处理,并在每次插入时增加相应索引处的值。这在 O(n) 时间内排序,额外内存 O(n)。

【讨论】:

    【解决方案4】:

    这里有一些代码:

    IntegerSort (Array A):
       Dimension Work as Array[1..750]
    
       Fill Work with (0)
    
       For i:=0 to A.Length - 1 
         Work[A[i]]++
    
       n = 0;
       For i:=1 to 750
          For j :=1 to Work[i] 
             A[n++] = i
    

    由于所有循环都是 O(n),因此算法也是 O(n)。

    在数组Work 中,该数组跨越整个数字范围并以 0 进行初始化,将每个元素 Work[k] 加一,对于 A 的所有元素,k=A[i]。

    现在通过扫描Work 数组来重建数组。任何 >0 的元素都表示原始数组中的一个或多个元素。当我们从 1 扫描到 750 时,我们将重建排序后的数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      相关资源
      最近更新 更多