並べ替えられていない配列の中央値を見つけるには、n要素に対して時間で最小ヒープを作成し、中央値を取得するためにn / 2要素を1つずつ抽出します。ただし、このアプローチにはO (n log n )時間かかります。
時間に何らかの方法で同じことを行うことはできますか?できるなら、どうやって?
並べ替えられていない配列の中央値を見つけるには、n要素に対して時間で最小ヒープを作成し、中央値を取得するためにn / 2要素を1つずつ抽出します。ただし、このアプローチにはO (n log n )時間かかります。
時間に何らかの方法で同じことを行うことはできますか?できるなら、どうやって?
回答:
これは、kが配列のサイズの半分である配列のk番目に小さい要素を見つけることができる選択アルゴリズムの特殊なケースです。最悪の場合、線形の実装があります。
まず、配列のk番目に小さい要素find-kth
を見つけるアルゴリズムを見てみましょう。
find-kth(A, k)
pivot = random element of A
(L, R) = split(A, pivot)
if k = |L|+1, return pivot
if k ≤ |L| , return find-kth(L, k)
if k > |L|+1, return find-kth(R, k-(|L|+1))
関数のsplit(A, pivot)
戻りL,R
のすべての要素は、そのようなR
より大きいpivot
とL
その他(マイナスの発生pivot
)。その後、すべてが再帰的に行われます。
これは、の平均が、でO (N 2)最悪の場合。
より適切なピボットは、A
サイズ5のサブ配列のすべての中央値の中央値です。これらの中央値の配列でプロシージャを呼び出して使用します。
find-kth(A, k)
B = [median(A[1], .., A[5]), median(A[6], .., A[10]), ..]
pivot = find-kth(B, |B|/2)
...
これにより、すべての場合にが保証されます。それほど明白ではありません。これらのPowerPointスライドは、アルゴリズムと複雑さの両方を説明するのに役立ちます。
ほとんどの場合、ランダムピボットを使用した方が速いことに注意してください。
5
標準ですか?Aのサイズが5より小さい場合はどうなりますか?
return A[k]
は正しくありません(A
アルゴリズムが意味をなさないように並べ替えられていない限り)。場合split
分けに起こったA
ようなk = |L| + 1
場所あなたはまだ知らないk
番目の要素があります。基本ケースは|A| = 1
、2つの再帰呼び出しのいずれかを行う必要がある場合です。