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

Popular Posts