web-dev-qa-db-ja.com

中央値を追跡する最良の方法は何ですか?

私は質問を読み、それを解決する方法についての入力を探しています。

数値はランダムに生成され、(拡張)配列に格納されます。中央値をどのように追跡しますか?

問題を解決できる2つのデータ構造があります。 1つはバランスのとれたバイナリツリーで、もう1つは2つのヒープで、要素の最大の半分と最小の半分を追跡します。これらの2つのソリューションの実行時間はO(n lg n)と同じだと思いますが、自分の判断はわかりません。

中央値を追跡する最良の方法は何ですか?

私の試み:

この質問では、中央値を追跡するにはヒープが最良の方法だと思います。大きなヒープと小さなヒープの2つのヒープがあり、これらは順次である必要はありません。まず、配列の要素の平均値を計算します。要素が平均値より小さい場合は、numを小さなヒープに入れます。逆に、numを大きなヒープに入れました。大きいヒープの数が小さいヒープの数と等しい場合、小さいヒープの最大のヒープと大きいヒープの最小のヒープが中央値になります。 2つのヒープのサイズが異なる場合は、大きなサイズのヒープからルート要素をポップし、それを小さなサイズのヒープのルートにプッシュします。大きなヒープの場合、ルート要素は最小の要素であり、小さなヒープの場合、ルート要素は最大の要素です。このようにして、2つのヒープが同じサイズまたはデジタル差異を持つ場合、ルートにメディアが見つかります。

このソリューションの実行時間はO(m * n)であると思います。mは、アンバランスヒープを調整する時間を意味します。

これは中央値を追跡する最良の方法ですか?

8
Steven Mou

この問題を解決するデータ構造はおそらく2つ以上あるでしょう。 概算中央値とその他の分位数をワンパスで、限られたメモリで確認してください

2つのヒープは使用しません。定期的に中央値の概算値を取得するように、アルゴリズムを変更できると思います。もちろん、近似がどの程度優れているかは、多くの要因に依存します。少なくとも、アルゴリズムを通過したデータの量はそうではありません。

1
Bruce Ediger

実際、O(n)演算では、kを見つけることによってのみ中央値を見つけることができます番目 リストの最小数、:)詳細は 中央値選択アルゴリズムの中央値 を調べます。

0
Ruslan Kabalin

より良い解決策は、スキップリストを使用することです。挿入先のリストは常にソートされたリストとして維持されているため(作成方法そのものにより)、挿入の複雑さはO(log n)です。最初の挿入によって中央値がゼロのコストで提供されるという事実を利用します(挿入されたアイテムは中央値です)。追加の挿入が行われるたびに、リストは引き続きソートされ、中央値自体が単一のインデックスによって上下にドリフトします。この比較はO(1)です。

総複雑度= O(log n)

0
Michael Hays