長い時間は10月忙しい母親の祖国の誕生日Amby(私はこれがブログを書くないとの理由ではないことを知っている)、11月初旬には本当に飼料の研究室を中心に実行するために、ブログを書いていない、出張は、忙しいです打撲とボロボロ、まだ具体的な成果がない背中を知りません。物事を買うために悪い二から一一が、彼らは言った、二から一一偽の売上高を買っていない、実際には、私が二から一一は、今年の過去の売上に基づいているかもしれない前に、これは与えられたKPI内部の大企業であるだろうと思い固定率分布の売上高は、外出先になってきたし、手を切るためにすべての人の能力は、単に要件を満たすために、それのすべての満足を失望させませんでした。私はので、それはそれを簡略化する、以下のルーチン、emmmmジドデシル。脱線、使用前に、今話題に戻って、今日、 コンパレータインタフェースは あなたと共有するいくつかの質問をして。
問題の説明
非ヌル整数配列、最初の戻りの発生頻度所与 K 高い要素。
例1:
入力:NUMS = [1,1,1,2,2,3]、K = 2 出力:[1,2]
注:あなたは、常に与えられた合理的なKを想定することができ、および配列の要素数が同じ1≤K≤ではありません。アルゴリズムのあなたの時間の複雑さは、(N Nログ)Oよりも良く、nは配列のサイズである必要があります。
問題の解決策
トピック説明は倍の数は、各要素は、統計が出てくるだけに表示され、その後、出現数に最初のk個の要素を取る、非常に簡単です。
方法A:キーの降順で地図値を使用してハッシュ+
1 / ** 2 * + 20msのをソートするためのハッシュキーマップに 3 * @param NUMS INTアレイ 。4 * @param 最初のk個のk番目の最大周波数 。5 * @return k個の要素 。6 * / 7 パブリックリスト<整数> topKFrequent(INT [ ] NUMS、int型K){ 8。 地図<整数、整数> =ハッシュ新しい新規のHashMap <> (); 9。 ため(INT A:NUMS){ 10 hash.put(A、hash.getOrDefault(A、0)+ 1 ) ; 11 } 12 13 リスト<のMap.Entry <整数、整数>>リスト= 新規のArrayList <> (hash.entrySet())。 14 Collections.sort(リスト、新しいコンパレータ<のMap.Entry <整数、整数>> (){ 15 公共 のint比較(のMap.Entry <整数、整数> O1、 16 のMap.Entry <整数、整数> O 2){ 17 リターン。o2.getValue()のcompareTo(o1.getValue()); 18 } 19 }); 20 21 一覧<整数> RET = 新規のArrayList <> (); 反復子<のMap.Entry <整数、整数>>それ= list.listIterator()。 23 一方(it.hasNext()&& K> 0 ){ 24 のMap.Entry <整数、整数>エントリ= it.next()。 25 ret.add(entry.getKey())。 26 K - 。 27 } 28 リターンRET。 29 }
ソートの時間計算量はO(nlgn)であり、nはマップ、条件の大きさであるからです。
方法2:小さなスタックトップストレージ・キーを使用して、対応するキー値に従って昇順でソート
1 / ** 2 * +ハッシュヒープソート19msをマッピングする 。3 * 4 Javaヒープ内*デフォルトは小さなトップで、スタックの要素がキーであるが、それはコンパレータに渡され、コンパレータを実装されているので、対応する比較値である 。5 * / 6 パブリック 静的リスト<整数> topKFrequent2(INT [] NUMS、int型K){ 7。 地図<整数、整数>マップ= 新しい新規のHashMap <> (); 8。 9。 // キー:NUMS要素値:キーが表示され数 10 のための(int型A:NUMS){ 11。 map.put(A、map.getOrDefault(A、0)+ 1 ); 12れる } 13のIS 14 優先度つきキュー<整数>のminheap = 新しい優先度つきキュー<>(新しいコンパレータ<整数> (){ 15 @Override 16 公共 のint 比較(整数、整数B){ 17 // 升序 18 戻り map.get() - マップ。 (B)を得る; 19 } 20 }); 21 22 のために(int型キー:map.keySet()){ 23 であれば(minHeap.size()< K){ 24 minHeap.offer(キー)。 25 } 他 もし(map.get(キー)> map.get(minHeap.peek())){ 26 minHeap.poll()。 27 minHeap.offer(キー)。 28 } 29 } 30 リターン 新規のArrayList <> (のminheap)。 31 }
スタックの時間複雑性の構造であるので、O(klgk)を、保守作業時パイルO(LGK)の最大高さの複雑さ、n回最大維持時間の複雑性O(nlgk)ので、毎回新たな要素を挿入します条件を満たすことができます。
第二の問題の説明
戻る前に、言葉の非空のリストに k個の 単語が表示されるの番目の最大数を。
答えは、周波数ワードが表示され降順にソート返されるべきです。同じ単語が異なる周波数を有する場合には、アルファベット順にソート。
入力:[ "I"、 "愛 "、 "leetcode"、 "I"、 "愛"、 "コーディング"]で、k = 2
出力:[ "I"、 "愛 "]
分析: "I"と「愛二つの言葉は、最も頻繁に現れるよう」、2回です。
注、「I」「愛」の前にアルファベット順でいます。
入力:[ ""、 "日 = 4、K"、 "ある"、 "晴れ"、 ""、 ""、 ""、 "晴れ"、 "である"とは、 "ある"]
出力:[ 、「ある」「」、 「晴れ」、「日」]
解決:「」、「ある」 「晴れ」、 および「日」4つの単語が最も頻繁に表示され、
出現数は4、3でした、 2と1。
問題の解決策
この質問と同じ考えに疑問、唯一の統計的な周波数と、その後の文字列を注文するだけでなく、2つの文字列が同じ番号を表示された場合に注意を払うが、その後、辞書式の文字列に応じてソート。出力列における前提に対応するには、発生の降順、文字列の出現の同じ数の昇順に、文字列辞書出力に出力されます。ので、2つの異なる照合、比較器に導入し、決意を複数の条件です。
方法の一つ:ハッシュ+ソート地図
保存されたハッシュのTreeMapを使用して、デフォルトのキーはの辞書式順序に格納されます
1 / ** 2 *マップソートハッシュ+ 11ms以下までの、時間の複雑さはO(mlgm)であり、mは異なる文字列のM種類を表す 。3 * @paramのS 。4 * @paramのKを 5 * @returnを 6 * / 7 パブリックリスト<ストリング> topKFrequent(文字列[] S、int型K){ 8。 ハッシュ=地図<文字列、整数> 新しい新規のTreeMap <> (); 9。 10 用(STR文字列:S){ 11。 hash.put(STR、hash.getOrDefault (STR、0)+ 1 ); 12である } 13である 14 リスト<のMap.Entry <文字列、整数>>一覧= 新しい ArrayListを<> (hash.entrySet()); 15 16 Collections.sort(リスト、新しいコンパレータ<のMap.Entry <文字列、整数>> (){ 17 公共 のint比較(のMap.Entry <文字列、整数> O1、 18 のMap.Entry <文字列、整数> O 2){ 19 // リスト会降序 20 リターンo2.getValue()のcompareTo(o1.getValue()); 21 } 22 }); 23 24 反復子<のMap.Entry <文字列、整数>>それ=list.listIterator(); 25 リスト<文字列> RET = 新しい ArrayListを<> (); 26 一方(it.hasNext()&& K> 0 ){ 27 のMap.Entry <文字列、整数>エントリ= it.next()。 28 ret.add(entry.getKey())。 29 K - 。 30 } 31 リターンRET。 32 }
方法2:ハッシュ+ヒープソート
答えは、出力周波数と逆の順序で出力文字列、出力文字列辞書式順序の同じ数に応じているので。したがって、スタックが格納されている場合に、発生のシーケンス番号に従って並べ替え、同様の番号は、発生辞書降順にソート。最後に、逆表情込ま時間の結果と、その後は、我々は尋ねた質問の結果を取得します。
1 / ** 2 * +ヒープソートハッシュ9ミリ秒、全体的な複雑さはO(nlgk)に達し、n個の文字列であり、kはヒープのサイズです。 。3 * @param Sストリング 。4 * @paramの数K 5つの * @return ストリング 。6 * / 7 パブリックリストの<string> topKFrequent2(文字列[] S、INT {K) 。8 地図<文字列、整数> =ハッシュ新しい新規のHashMap < > (); 9。 10 用(STR文字列:S){ 11 hash.put(STR、hash.getOrDefault(STR、0)+ 1 ); 12である } 13であります 14 優先度つきキューの<string> H = 新しい優先度つきキュー<>(新しいコンパレータの<string> (){ 15 @Override 16 公共 のint 比較(String型O1、文字列O2){ 17 リターン hash.get(O1).equals(hash.get( O2))? 18 // 按照次数升序 19 // o2.compareTo(O1):hash.get(O1).compareTo(hash.get(O2)); 20 o2.compareTo(O1):(hash.get( O1) - hash.get(O2)); 21 } 22 }); 23 24 //キーは、ルールは、それらが同じ数である場合にキー辞書に従って降順に、発生したキーの数の昇順に格納される、に記憶されている 25 のために{(hash.keySet()は、文字列キー) 26がある h.offer(キー) ; 27 IF(h.size()> K)h.pollは(); 28 } 29 30 // 結果を保存し、また、辞書によると、これは数、単語の同一の数に従って降順で達成され、それを逆にする必要があります昇順 31が リストの<string> RET = 新しい新規のArrayList <> (); 32 ながら(!ret.add(h.poll())h.isEmpty()); 33は 34である 。Collections.reverse(RET) 35 リターンRET。 36 }