Input:
words = ["i","love","leetcode","i","love","coding"], k = 2
Output:
["i","love"]
Explanation: "i" and "love" are the two most frequent words.
Note that "i" comes before "love" due to a lower alphabetical order.
Example 2:
1
2
3
4
5
Input:
words = ["the","day","is","sunny","the","the","the","sunny","is","is"], k = 4
Output:
["the","is","sunny","day"]
Explanation: "the", "is", "sunny" and "day" are the four most frequent words, with the number of occurrence being 4, 3, 2 and 1 respectively.
Method 3 - Using MinHeap with K Elements- O(nlgk) Solution with O(n) Space#
But we can improve this solution. Note that we are only concern about the top k elements. Sorting the array means we are sorting all the n elements which is unnecessary as we are only concerned for first k. Any idea popping in? Yeah, I am sure you have the same feeling that we could use a Min Heap of size k to keep top k most frequent words. That’s right. We also need to use a hashmap to keep frequency of each word.
Calculated frequency of all the words in a hashmap from the word to its frequency.
Start adding pair object of word and its frequency into a min heap where we use the frequency as the key for the min heap.
If the heap is full then remove the minimum element (top) form the heap and add add the new word-frequency pair only if the frequency of this word has frequency greater than the top word in the heap.
Once we scanned all the words in the map and the heap is properly updated then the elements contained in the min heap are the top k most frequents.
public List<String>topKFrequent(String[] words, int k) {
Map<String, Integer> map =new HashMap<>();
for (String w : words) {
map.put(w, map.getOrDefault(w, 0) + 1);
}
Queue<Pair> minHeap =new PriorityQueue<>((a, b) -> (a.freq== b.freq) ? b.word.compareTo(a.word) : Integer.compare(a.freq, b.freq));
for (String w : map.keySet()) {
int f = map.get(w);
minHeap.offer(new Pair(w, f));
if (minHeap.size() > k) {
minHeap.poll();
}
}
LinkedList<String> result =new LinkedList<>(); // nOt using arraylist as it doesnt provide addFirst, otherwise we have to do collection reversewhile (!minHeap.isEmpty()) {
result.addFirst(minHeap.poll().word);
}
return result;
}
staticclassWordFreq {
String word;
int freq;
Pair(String word, int freq) {
this.word= word;
this.freq= freq;
}
}