1、タイトル説明:入力nは整数は、最小数Kを見つけます。4,5,1,6,2,7,3,8例えば8つのデジタル入力、最小数は4 1,2,3,4です。
2、思考:この質問は3つのソリューション、すなわち、ソート、分割統治、最大ヒープ(プライオリティキュー)を持っています
方法:次に、ソートの最初のk個を取って、複雑さ(nlogn)Oで最速時間をソート、第一の配列の入力をソート、ソートのための方法。合計時間の複雑さは、O(nlogn)です。
溶液2:分割統治法は、思考のクイックソートを模倣する、各時刻k-アレイの数をとり、その後、配列番号kの最初の数よりも大きいアレイの左側のk個の数よりも小さくなります右。そして、ダウン調整を続けます。時間計算量はO(N)です。
、することはできません。この方法は、理由は、配列の構造を変更する必要性のため、大量のデータに適していない、そしてメモリが十分な大きさでない場合、アレイ全体では、メモリにロードされなければなりません。
解決策3:最大ヒープ(プライオリティキュー)。各要素がキューから排出されることを保証するために、オーバーライドメソッドを比較するコンパレータを通過する、第一の容量プライオリティキューkを作成することは最大です。キューがいっぱいになったときに要素が優先され挿入されるように、要素がいる場合にのみ、スタックの要素の上部を比較する必要があるため、優先度キュー内の要素の数がk未満倍、単に数字のアレイから取り出されたキューに直接挿入することが可能です以下の要素を挿入するカスタム要素よりもヒープ、要素がヒープに挿入されるならば、要素の小さなセットよりも、あきらめて、それがヒープbook要素を削除しますが、配列要素が挿入されています。
このアプローチの利点は、アレイ構造が変化、小さなメモリフットプリントは、複雑さが(1)Oで最大スタック時間から最大k個の番号を取得する、大量のデータを処理するように適合しないことがあり、削除及び挿入要素の動作時間計算量はO(logk)です。したがって、この方法の全体的な時間計算量はO(nlogk)です。以上が、ほぼ二大容量データ記憶装置に適したソリューション。
3、コード:ダイレクトコピー、自分自身を達成するために、後者の必要性
輸入はjava.util.ArrayList; 輸入java.util.PriorityQueue; 輸入はjava.util.Comparator; パブリック クラスソリューション{ 公共のArrayList <整数> GetLeastNumbers_Solution(INT []入力、INT K){ のArrayList <整数>結果= 新規のArrayList <整数> (); int型の長さ= input.length。 もし(K>長|| K == 0 ){ リターン結果。 } 優先度つきキュー <整数> maxHeap = 新しい優先度つきキュー<整数>(K、新しい新しいコンパレータ<整数> (){ @Override 公共 INT (O1整数、整数O2)比較{ 戻りo2.compareTo(O1)を; } }); のための(INT I <長さ; I ++ I = 0 ){ IF(maxheap !.size()= K){
//最大スタックk個の要素を直接挿入しない maxHeap.offer(INPUT [I]); } そう IF(maxHeap.peek()> INPUT [I]){
//最大挿入するヒープ比較要素と要素の上に重ね
ヒープに//挿入される小さな要素を、削除された最大の要素、要素のヒープの、トップ
TEMP整数 =maxHeap.poll(); 温度 = nullを。 maxHeap.offer(入力[I])。 } } のための(整数整数:maxHeap){ result.add(整数)。 } 戻り値の結果; } }