これはインタビューの質問です。整数を格納し、2 つの操作を提供するクラスを設計します。
無効な挿入 (int k) int getMedian()
insertO(logN)とO(logN)を取るようにBSTを使用できると思いますgetMedian(getMedian各ノードの左/右の子の数を追加する必要があるため)。
これが最も効率的な解決策であり、これ以上の解決策はないのではないかと思います。
これはインタビューの質問です。整数を格納し、2 つの操作を提供するクラスを設計します。
無効な挿入 (int k) int getMedian()
insertO(logN)とO(logN)を取るようにBSTを使用できると思いますgetMedian(getMedian各ノードの左/右の子の数を追加する必要があるため)。
これが最も効率的な解決策であり、これ以上の解決策はないのではないかと思います。
Leftと呼ばれる 2 つのヒープを使用できますRight。
LeftですMax-Heap。
RightですMin-Heap。
挿入は次のように行われます。
xが のルートよりも小さい場合はLeft、 に挿入xしLeftます。xしRightます。LeftAfter insertの要素数が の要素数から 1 より大きい場合、RightExtract-Max を呼び出してに挿入LeftしRightます。Rightの要素数が の要素数より多い場合は、LeftExtract-Min を呼び出してRightに挿入しLeftます。中央値は常に の根ですLeft。
したがって、挿入は時間内O(lg n)に行われ、中央値の取得は時間内に行われO(1)ます。
2 つのヒープを含むソリューションについては、このスタック オーバーフローの質問を参照してください。
O < O(log(n) ) 配列を使用すると、getMedian はサイズの半分でインデックスを取得し、O(1) になりますよね? log(n) + log(n) よりもうまくいくように思えます。
さらに、もう少し柔軟にすることで、入力のプロパティに応じてソートアルゴリズムを変更することでパフォーマンスを向上させることができます (入力がほとんどソートされているかどうか...)。
私はほとんどコンピューター サイエンスを独学で学んでいますが、それが私のやり方です。
自己均衡ツリーも考えられます。ツリーが完全にバランスが取れている場合、ルート ノードは中央値です。たとえば、ツリーの一方の端が 1 レベル深いとします。次に、正しい中央値を選択するために、より深い側にいくつのノードがあるかを知る必要があります.