n個のアイテムのトップmを得るための複雑さをO(n log m)とする、「ヒープの先頭のピーク」アルゴリズムに加えて、もう2つのソリューションがあります。
解決策1:フィボナッチヒープを使用します。
JDKのPriorityQueue実装は、バランスの取れたバイナリヒープです。 Fibonacci heapの実装より多くのパフォーマンスを絞ることができるはずです。償却された一定時間の挿入があり、バイナリヒープに挿入するときにヒープのサイズに複雑さΩ(log n)があります。あなたがすべての要素についてそれをしているなら、あなたはΩ(n log n)にいます。 Fibヒープを使用してn個のアイテムのトップmを見つけることは、複雑さO(n + m log n)を有する。これをヒープにm個の要素を挿入するだけの提案と組み合わせると、線形時間に近いO(n + m log m)が得られます。
解決策2:リストをM回横断します。
O(n)回の集合でk番目に大きい要素を得ることができるはずです。すべてをリストに読み込んで、以下を実行してください:
kthLargest(k, xs)
Pick a random pivot element p from the list
(the first one will do if your list is already random).
Go over the set once and group it into two lists.
Left: smaller than p.
Right: Larger or equal to p.
If the Right list is shorter than k, return kthLargest(k - right.size, Left)
If the Right list is longer than k, return kthLargest(k, right)
Otherwise, return p.
これはあなたにO(n)時間を与えます。それをm回実行すると、時間がO(nm)のセット内のトップmのオブジェクトを得ることができるはずです。これは、十分に大きいnと十分に小さいmのn log nよりも厳密に小さくなります。たとえば、トップ10を100万アイテム以上にすると、バイナリヒープ優先度キューを使用する場合の半分の時間がかかりますが、それ以外はすべて等しいことになります。
このコードでプロファイラを実行しましたか?コンパレータはどのように書かれていますか? –
公共INT比較(ListElement I、ListElementのJ){ \t \t \t \t \t \t \t IF(i.getValue() - j.getValue()> 0) リターン1。 else 戻り値-1; } – BigG
あなたのコードをプロファイルして、コードがあなたの好きなものよりも遅く実行されている原因を突き止めることを強くお勧めします。コードは表示されず、追加情報もなくこの質問に答えるのは難しいです。どの部分が遅いですか? –