Leetcode: Top K Frequent Words
This question is asked extremely commonly at Amazon, and relatively commonly at Bloomberg, Facebook, and Google. It asks the following:
Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted by frequency from the highest to lowest, and if 2 words have the same frequency, the word with the lowest alphabetical order comes first, which I believe will require sorting, and prevention of the use of an equivalent operator. We want to solve it in O(n log k) time, which I believe might use a priority queue or heap tree. Inputs only contain lowercase letters, so fortunately we have to do too much conversion here.
Here are some examples:
Example 1:
Input: ["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:
Input: ["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.
and now here comes the algorithm.
The idea was to keep each frequency of each word in a HashMap and insert it subsequently into a Priority Queue. If the count of words is the same, then insert the word based on the key comparison after that. Here is the code with comments:
class Solution {
public List<String> top KFrequent(String[] words, int k) {
//initialize the list and the hashmap.
List<String> result = new LinkedList<>();
Map<String, Integer> map = new HashMap<>();
//put all of the words into the hashmap.
for(int i = 0; i < words.length; i++) {
if(map.containsKey(words[i])
map.put(words[i], map.get(words[i]) + 1);
else
map.put(words[i], 1);
}
//initialize a priority queue of hashmaps with the rules inside of the priority queue
//this priority queue uses the comparison operator and uses the maximum value.
PriorityQueue<Map.Entry<String, Integer>> pw = new PriorityQueue<>( (a,b) -> a.getValue() == b.getValue() ? b.getKey().compareTo(a.getKey()) : a.getValue() - b.getValue());
//offer the first k elements of the set
for(Map.Entry<String, Integer> entry: map.entrySet()){
pq.offer(entry);
if(pq.size() > k) pq.poll();
}
//extract the first k elements and put them into result.
while(!pq.isEmpty()){
result.add(0, pq.poll().getKey());
}
return result;
}
}


Comments
Post a Comment