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