N個の変数があり、それぞれにm個の可能な値がある場合。 (整数の場合、mは20億の何かです。)
まず、可能なすべての値を0からm-1までの整数に順番にマッピングします。そして、マッピング関数を定義します。
index(v): value to integer
value(i): integer to value
次に、n個の変数をループし、すべての値が出現した回数を数えます。
for v in variables {
counter[index(v)] += 1
}
最後に、counter配列をループして、結果の配列に値を入れます。
for i in 0...m-1 {
for j in 1...counter[i] {
result.append(value(i))
}
}
結果の配列はソートされ、このアルゴリズムの複雑さはO(n + m)です。
大きいnと小さいmの場合、O(n * log(n))よりも優れている可能性があります。
おめでとうございます、あなたはcounting sortを再発明しました! (私は皮肉ではありません、物事が独立して何度も再発明されていることは良いことであり、問題を解決する自然で良い方法であることを示しています。)
ソートのカウントの時間の複雑さは、確かにO(n * log n)よりも優れています。 「ソート」のために通常引用されるΩ(n * log n)の「バリア」はwrongであることに注意してください。これは比較ベースのソートの下限であり、notはallソートの下限です。
特に、ソートのカウントは比較に基づいていないため、比較ベースのソートの下限は適用されません。
nが大きい場合、log(n)は明らかに1より大きく、n * log(n)はnより大きい。 mがnと比較して非常に小さい場合、O(n + m)はO(n)に近い。したがって、これらの特定の条件では、アルゴリズムが高速になります。
しかし、この優れた時間パフォーマンスは、スペースパフォーマンスを犠牲にしています。