1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| import java.util.*;
public class KFrequentWords2 { private final int k; private final WordInfo[] heap, help; private final HashMap<String,WordInfo> wordMap; private final HashMap<WordInfo,Integer> indexMap; private int size; private final Comparator<WordInfo> heapCmp = (a,b) -> a.cnt != b.cnt ? a.cnt - b.cnt : a.word.compareTo(b.word); private final Comparator<WordInfo> sortCmp = (a,b) -> a.cnt != b.cnt ? b.cnt - a.cnt : b.word.compareTo(a.word); public KFrequentWords2(int k) { this.k = k; heap = new WordInfo[k]; help = new WordInfo[k]; wordMap = new HashMap<>(); indexMap = new HashMap<>(); } public void add(String word) { WordInfo wi = wordMap.get(word); if(wi == null) { wi = new WordInfo(word); wordMap.put(word,wi); }else ++wi.cnt; Integer index = indexMap.get(wi); if(index == null) { if(size < k) { heap[size] = wi; indexMap.put(wi,size); heapInsert(size++); }else { if(heapCmp.compare(heap[0],wi) < 0) { indexMap.put(wi,0); indexMap.remove(heap[0]); heap[0] = wi; heapIfy(0); } } }else heapIfy(index); } public List<String> getTopKWords() { int len = Math.min(k,size); List<String> ans = new ArrayList<>(len); for(int i = 0; i < len; ++i) help[i] = heap[i]; Arrays.sort(help,0,len,sortCmp); for(int i = 0; i < len; ++i) ans.add(help[i].word); return ans; } private void heapInsert(int index) { int parent; while(heapCmp.compare(heap[index],heap[parent = (index - 1) / 2]) < 0) { swap(index,parent); index = parent; } } private void heapIfy(int index) { int child, bnd = size >> 1; while(index < bnd) { child = (index << 1) | 1; if(child + 1 < size && heapCmp.compare(heap[child],heap[child+1]) > 0) ++child; if(heapCmp.compare(heap[index],heap[child]) <= 0) break; swap(index,child); index = child; } } private void swap(int i, int j) { WordInfo wi = heap[i], wj = heap[j]; indexMap.put(wi,j); indexMap.put(wj,i); heap[i] = wj; heap[j] = wi; } static class WordInfo { private String word; private int cnt; public WordInfo(String word) { this.word = word; cnt = 1; } } public static void main(String[] args) { KFrequentWords2 kfw = new KFrequentWords2(3); kfw.add("hello"); kfw.add("yes"); kfw.add("C++"); System.out.println(kfw.getTopKWords()); kfw.add("yes"); kfw.add("yes"); kfw.add("yes"); System.out.println(kfw.getTopKWords()); kfw.add("C++"); kfw.add("C++"); kfw.add("C++"); System.out.println(kfw.getTopKWords()); } }
|