抽出定数の最高値のリスト
質問
を求めている表示一定数の項目をウェブページにそれぞれの量で表される Integer
).のリストがこれらの項目は見つかりできるの質問です。
最初の溶液に浮い Collections.sort()
やの項目を一つ一つを通ることにより List
.あまりエレガントな解決方法が使用できる、と言うことになると、イベントは、ホームページのだろう?
解決
だけはCollections.sort(..)
のために行きます。それは効率的で十分です。
このアルゴリズムが提供する保証のn(n)のパフォーマンスを記録します。
あなたがのあなたのリストのいくつかの特徴的な性質を知っているが、それは正当化されないならば、あなたの具体的なケースのためにのより効率的な何かを実装しようとすることができます。あなたのリストがデータベースから来る場合また、例えば、あなたはコードではなく、そこに&ためにそれをLIMIT
することができます。
他のヒント
オプション:
い
直線検索維持のためのウェイト見つかりました。これ以上に早く並べ替えlengthlyリストが何らかの理由で、再利用、分別結果の間に表示するページの例このリストは変化に迅速に).更新:台修正、線形探索ているとは限ります。見Wikipedia記事"Selection_algorithm選択k最小又は最大の要素"より良い選択アルゴリズム
手動で維持
List
平または並列)に並び重量です。利用できるという方法 ョンにします。binarySearch() の決定が挿入それぞれの新しい商品です。を維持
List
平または並列)に並び重量によるの呼び出し ョンにします。sort() 後に変更、一括変更は、直前に表示する維持修正フラグを避けるソート済みのソートします。.使用データの売れ筋が見える、販売戦略がソートの重量のため専用に作成する方法もあります。 優先度キュー, ツリーセット, など。きものを自分のデータ構造です。
手動で維持秒(重量-らわれ、[]内に示したデータ構造のN。このデータ構造の更新をいつでも元のデータ構造が変更されます。することができ独自のデータ構造を包む独自のリストは、この"上位N個のキャッシュします。
あなたは最大ヒープに使用することができます。
データベースからのデータの発信元であれば、その列にインデックスを入れて、あなたが表示する必要がある唯一のレコードを取得するためにORDER BYとTOPまたはLIMITを使用します。
またはプライオリティキューに。
ドルを使用します:
List<Integer> topTen = $(list).sort().slice(10).toList();
ドルを使用しないあなたはsort()
を使用して最初のn個のアイテムを取得し、その後、Collections.sort()
を使用して、それをlist.sublist(0, n)
必要があります。
あなたは、Nは任意のサイズであってもよい、と私は仮定大きくなることがあり、私は完全に合理的なサイズの入力に適しています(上記の単純なsort()
回答を強化したいこれらのトップを抽出するために、そこから項目のリストを言うので、そして、これらのNは自明であるソート - )、ここでの仕事のほとんどを示唆することにより、トップNを見つけることです。それは次のとおりです。
Queue<Integer> topN = new PriorityQueue<Integer>(n);
for (Integer item : input) {
if (topN.size() < n) {
topN.add(item);
} else if (item > topN.peek()) {
topN.add(item);
topN.poll();
}
}
List<Integer> result = new ArrayList<Integer>(n);
result.addAll(topN);
Collections.sort(result, Collections.reverseOrder());
ここでヒープ(MIN-ヒープ)は、少なくともサイズが制限されます。すべてのアイテムのうち、ヒープをする本当の必要はありません。
いや、そうでもありません。少なくともJavaの内蔵のメソッドを使用していません。
があり迅速O(n*log(n))
操作よりも、リストから項目の最高(または最低)Nの番号を取得するための巧妙な方法がありますが、それは手で、このソリューションをコーディングする必要がします。 (ないより百のカップルよりも)アイテム滞在の数が比較的低い場合は、Collections.sort()
を使用してそれをソートして、上位N個の数字をつかむことはIMO移動するための方法である。
どのように多く依存します。表示したい数として合計キーの数、およびmとnは定義することができます。
O(nlogn)
:全体のことをソート
O(n*m)
:配列に次の最高数のたびにスキャン
質問があるので、 - ?メートル
へのnの関係は何ですか
m < log n
場合、スキャンは、より効率的になります。
そうでなければ、手段はソートm >= log n
は、良くなります。 (m = log n
のエッジケースのためので、それは実際には重要ではありませんが、ソートすることも、常にいいです配列を、並べ替え、よく、あなたの利益を得られます。
は、優先順位にリスト変換リスト(インデックス可能でなければならない、例えばアレイ)上Heapifyを呼び出す必要がキュー。 ( http://en.wikipedia.org/wiki/Heapsort の中heapify関数を参照してください)
は、ヒープ(MAXアイテム)の上にアイテムを取得することは、時間(N LG)Oをとります。だからあなたの全体の時間は次のようになります:
O(N + K LG N)
良好O(N LG N)はkがNよりもはるかに小さいと仮定よりも
は、次のような何かを試みることができます。 O時間は、大きな配列のソートと同様であるが、実際には、これは、より効率的であるべきである。
small_array = big_array.slice( number_of_items_to_find );
small_array.sort();
least_found_value = small_array.get(0).value;
for ( item in big_array ) { // needs to skip first few items
if ( item.value > least_found_value ) {
small_array.remove(0);
small_array.insert_sorted(item);
least_found_value = small_array.get(0).value;
}
}
small_arrayは、[オブジェクトとすることができる]及び内部ループはスワップの代わりに実際に除去し、アレイに挿入して行うことができる。