時間で並べ替えられていない配列の中央値を見つける


45

並べ替えられていない配列の中央値を見つけるには、n要素に対して時間で最小ヒープを作成し、中央値を取得するためにn / 2要素を1つずつ抽出します。ただし、このアプローチにはO n log n 時間かかります。Onログnnn/2Onログn

時間に何らかの方法で同じことを行うことはできますか?できるなら、どうやって?On



1
@JukkaSuomelaなぜこれをすばやく簡単な答えにしないのですか(理想的には、そのようなアルゴリズムの簡単な説明付き)?
ラファエル

2
関連するメタディスカッションに注意してください。結局のところ、単純なWeb検索はこの質問に対する答えにつながります。
ラファエル

回答:


45

これは、kが配列のサイズの半分である配列のk番目に小さい要素を見つけることができる選択アルゴリズムの特殊なケースです。最悪の場合、線形の実装があります。kk

汎用選択アルゴリズム

まず、配列のk番目に小さい要素find-kthを見つけるアルゴリズムを見てみましょう。k

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より大きいpivotLその他(マイナスの発生pivot)。その後、すべてが再帰的に行われます。

これは、の平均が、でO N 2最悪の場合。OnOn2

線形最悪の場合:中央値アルゴリズム

より適切なピボットは、Aサイズ5のサブ配列のすべての中央値の中央値です。これらの中央値の配列でプロシージャを呼び出して使用します。

find-kth(A, k)
  B = [median(A[1], .., A[5]), median(A[6], .., A[10]), ..]
  pivot = find-kth(B, |B|/2)
  ...

これにより、すべての場合にが保証されます。それほど明白ではありません。これらのPowerPointスライドは、アルゴリズムと複雑さの両方を説明するのに役立ちます。On

ほとんどの場合、ランダムピボットを使用した方が速いことに注意してください。


このサイズは5標準ですか?Aのサイズが5より小さい場合はどうなりますか?
Jayesh

固定nの場合、無限でない限り、複雑さは一定です。したがって、O(2 ^ n)であっても、このような特別な場合には有限の複雑さを持つ有効なアルゴリズムを使用できます。固定のn(つまり、最大で4)の場合、複雑さは最大でO(2 ^ 4)= O(1)です。
v6ak

3
最初のアルゴリズムでは:return A[k]は正しくありません(Aアルゴリズムが意味をなさないように並べ替えられていない限り)。場合split分けに起こったAようなk = |L| + 1場所あなたはまだ知らないk番目の要素があります。基本ケースは|A| = 1、2つの再帰呼び出しのいずれかを行う必要がある場合です。
-wcochran

2
@NickCaplingerはweb.archive.orgを使用して修正されました
jmad

1
一般的な選択アルゴリズムの最悪のケースはO(NlogN)ではありませんか?でも、各コール後の配列の10%だけを再帰呼び出しの葉ならば、それはまだ基礎10の対数だ
オクタヴィアン

6

n1/4On

アルゴリズムの主なアイデアは、サンプリングを使用することです。配列の並べ替え順序で互いに近く、それらの間に中央値がある2つの要素を見つける必要があります。完全な議論については、リファレンス[MU2017]を参照してください。


[MU2017] Michael MitzenmacherとEli Upfal。「確率とコンピューティング:アルゴリズムとデータ分析におけるランダム化と確率的手法」、第3章、57〜62ページ。ケンブリッジ大学出版局、第2版、2017年。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.