AlgoMaster Logo

Top K Frequent Words

mediumFrequency7 min readUpdated June 23, 2026

Understanding the Problem

We have a list of words, some of which repeat, and we need to find the k most frequently occurring ones. So far this sounds identical to "Top K Frequent Elements," but there's a twist: when two words share the same frequency, they must be ordered alphabetically. The output must also be sorted by frequency (highest first), not returned in any order.

This tie-breaking requirement changes the problem. With numbers, you could return results in any order. Here, the custom sort has two keys: frequency (descending) and then lexicographic order (ascending). Every approach has to handle this dual ordering correctly, which is what drives the data structure choices below.

Key Constraints:

  • 1 <= words.length <= 500: With n at most 500, even an O(n^2) solution would pass. The follow-up still asks for O(n log k), so the goal is to reach that bound.
  • 1 <= words[i].length <= 10: Words are short, so a single string comparison costs at most 10 character comparisons. We treat each comparison as O(1) and leave the word length out of the complexity analysis.
  • words[i] consists of lowercase English letters, so there are no unicode or special-character cases to handle.
  • k is in [1, number of unique words], so k never exceeds the number of distinct words and the answer always has exactly k entries.

Approach 1: Sort by Custom Comparator

Intuition

Count every word's frequency, then sort the unique words using a comparator that handles both criteria: frequency descending first, and alphabetical order ascending to break ties. Take the first k words from the sorted list.

The comparator is the whole solution. Once the list is sorted by these two keys, the answer is the prefix of length k, and the output ordering is already correct because we sorted by the same keys the output requires.

Algorithm

  1. Build a hash map freq mapping each word to its count.
  2. Collect all unique words into a list.
  3. Sort the list with a custom comparator: compare by frequency descending first, then by word lexicographically ascending for ties.
  4. Return the first k words from the sorted list.

Example Walkthrough

words
1Scan words to build frequency map
0
i
1
love
2
leetcode
3
i
4
love
5
coding
freq
1Build frequency map from words
i
:
2
love
:
2
leetcode
:
1
coding
:
1
1/5

Code

Sorting orders all m unique words even though only k are needed. The next approach keeps a running set of only k candidates and discards the rest as it scans, which lowers the log factor from log m to log k.

Approach 2: Min-Heap

Intuition

A min-heap of size k holds the current top k candidates while we scan. Push each unique word into the heap, and when the heap grows past k, pop one word. After processing every word, the heap holds the top k.

The heap's comparator is the reverse of the output ordering. The result wants high frequency and, for ties, low alphabetical order. So the heap's minimum (the element that gets popped) must be the word that is worst by those criteria: lowest frequency, and for ties, highest alphabetical order.

Algorithm

  1. Build a frequency map from words.
  2. Create a min-heap with a custom comparator: compare by frequency ascending first (lower frequency = smaller = gets popped first), and for equal frequencies, compare by word descending alphabetically (alphabetically later = less desirable = gets popped first).
  3. For each unique word, add it to the heap. If heap size exceeds k, pop the minimum.
  4. Extract elements from the heap. Since the heap gives them in min-first order, reverse the result.

Example Walkthrough

freq
1Frequency map: i=2, love=2, leetcode=1, coding=1
i
:
2
love
:
2
leetcode
:
1
coding
:
1
min-heap
1Empty heap, will maintain size k=2
[]
1/6

Code

The heap approach meets the O(n log k) follow-up. The next approach removes the log factor on the frequency dimension by grouping words directly into buckets indexed by frequency, leaving only the per-bucket alphabetical sort.

Approach 3: Bucket Sort

Intuition

The maximum frequency any word can have is n, the case where every element is the same word. Create an array of n+1 buckets where bucket[i] holds all words with frequency i. Frequency is an integer in [1, n], so it serves directly as an array index without any comparisons. Walking from the highest bucket down to the lowest visits words in decreasing-frequency order.

Words sharing a bucket all have the same frequency, so they must come out in alphabetical order to satisfy the tie-breaking rule. Sorting each bucket on its own handles that. The combined size of all buckets is m unique words, so the total sorting cost stays bounded by O(m log m).

Algorithm

  1. Build a frequency map from words.
  2. Create a bucket array of size n+1. For each unique word, add it to bucket[frequency].
  3. Sort each non-empty bucket alphabetically.
  4. Walk from the highest index down to 0. For each bucket, collect words into the result until we have k words total.
  5. Return the result.

Example Walkthrough

freq
1Build frequency map from words
the
:
4
day
:
1
is
:
3
sunny
:
2
buckets
1Create bucket array, index = frequency
0
[]
1
[]
2
[]
3
[]
4
[]
1/6

Code