【问题标题】:Sorting Array in O(n) complexity以 O(n) 复杂度对数组进行排序
【发布时间】:2025-12-27 22:15:06
【问题描述】:

我在 Atrenta 的面试中被问到一个有趣的问题。这是对复杂度为 O(n) 的数组进行排序,我说这是不可能的,但他坚持认为这是不可能的,即使在面试之后也是如此。

是这样的。

您有一个数组,可以说:[1,0,1,0,1,1,0],这需要排序。必须在数组中完成的事情(在某种意义上不涉及其他数据结构。

我没有,我认为不可能做任何复杂度为 O(n) 的事情。我能想到的最好的是 O(n * log n),我的知识来自*。

如果你知道的话,请给我你的想法和方法。

【问题讨论】:

  • 阅读*关于排序的文章的其余部分。 O(n log n) 只需要应用于基于 comparison 的排序,而不是例如基数排序。
  • 这已在 SO 上被多次询问和回答,例如*.com/questions/7655659/….
  • 对数据集的任何约束都可能导致算法的简化。这里,如果数据为0和1,则桶排序为O(n+k),也就是O(n+2),也就是O(n)
  • 计数排序也可以。
  • 感觉非常可怕和羞愧... :D 你们是对的!所以限制就可以了。

标签: algorithm sorting


【解决方案1】:

在您的示例中,数组中只有两个不同的值,因此您可以使用计数排序:

zero_count = 0
for value in array:
    if value == 0:
        zero_count += 1
for i in 0 ... zero_count:
    array[i] = 0
for i in zero_count ... array.size:
    array[i] = 1

基数排序是一系列更普遍适用的 O(n) 排序。

比较排序平均需要 Omega(n * log n) 比较,因此不能在最坏情况或平均情况下的线性时间运行。

【讨论】:

  • 看起来像python,所以为了美观,array.count(0) 可以做到。 (但是,对于大 O 度量,for 循环当然更明确)
  • @njzk2:是的,它是受 Python 影响的伪代码。在实际的 Python 中,zeros = array.count(0); return [0] * zeros + [1] * (len(array) - zeros) 会这样做,但就像你说的那样,这并没有使复杂性变得非常明确。
【解决方案2】:

从两端遍历数组,并在需要时交换 1 和 0。在 O(n) 中运行,但具有所有 if 条件(bruteforce like approach.probably not the expected answer) ;)

int i = 0 ;
int j = array.size -1 ;
for ( i = 0 ; i < j ; ) {

    if( array[i] == 1) {
        if( array[j] == 0 ) {
            array[j] = 1 ; array[i] = 0 ; //Swap 
            i++; j--; 
            continue;
        }
        //else
            j--;
            continue;

    }
   //else
        if( array[j] == 0 ) {
            i++; 
            continue;
        }

        //else 
            i++ ;
            j--;            
}

【讨论】:

  • 我认为史蒂夫使用计数排序的答案是预期的答案
  • 两者都有效!这是一种排序,我猜这叫做计数!