Top K Frequent Words

medium string hash map heap

Problem

Given an array of strings words and an integer k, return the k most frequent strings. Sort the answer by frequency from highest to lowest. Sort words with the same frequency by lexicographic order.

Inputwords = ["i","love","leetcode","i","love","coding"], k = 2
Output["i", "love"]
"i" and "love" each appear twice; "i" comes first alphabetically.

import heapq
from collections import Counter
def top_k_frequent(words, k):
    cnt = Counter(words)
    heap = []
    for w, c in cnt.items():
        heapq.heappush(heap, (c, [-ord(ch) for ch in w], w))
        if len(heap) > k:
            heapq.heappop(heap)
    return [w for _, _, w in sorted(heap, key=lambda x: (-x[0], x[2]))]
function topKFrequent(words, k) {
  const cnt = new Map();
  for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
  return [...cnt.entries()]
    .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
    .slice(0, k)
    .map(([w]) => w);
}
class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> cnt = new HashMap<>();
        for (String w : words) cnt.merge(w, 1, Integer::sum);
        PriorityQueue<String> heap = new PriorityQueue<>((a, b) ->
            cnt.get(a).equals(cnt.get(b)) ? b.compareTo(a) : cnt.get(a) - cnt.get(b));
        for (String w : cnt.keySet()) {
            heap.offer(w);
            if (heap.size() > k) heap.poll();
        }
        LinkedList<String> ans = new LinkedList<>();
        while (!heap.isEmpty()) ans.addFirst(heap.poll());
        return ans;
    }
}
vector<string> topKFrequent(vector<string>& words, int k) {
    unordered_map<string, int> cnt;
    for (auto& w : words) cnt[w]++;
    auto cmp = [&](const string& a, const string& b) {
        return cnt[a] == cnt[b] ? a < b : cnt[a] > cnt[b];
    };
    priority_queue<string, vector<string>, decltype(cmp)> heap(cmp);
    for (auto& p : cnt) {
        heap.push(p.first);
        if ((int)heap.size() > k) heap.pop();
    }
    vector<string> ans;
    while (!heap.empty()) { ans.push_back(heap.top()); heap.pop(); }
    reverse(ans.begin(), ans.end());
    return ans;
}
Time: O(n log k) Space: O(n)