Optimize the code · Easy

Speed Up the Most Frequent Word

Easy Make it fast Seen at Amazon, Bloomberg

mostFrequentWord(words) returns the word that appears most often. If several words share the highest count, return the alphabetically smallest of them.

The version below recounts the whole list for every word. It is correct, but a 50,000-word log takes far too long. Make it fast without changing the results.

Example 1

Input: words = ["b", "a", "b", "a", "c"]
Output: "a"
Explanation: a and b both appear twice; a is alphabetically first.

Constraints

  • 1 <= words.length <= 100000

The slow code

Every case must finish within 300 ms (budgets are per language in the editor).

function mostFrequentWord(words) {
  let best = null;
  let bestCount = 0;
  for (const w of words) {
    let count = 0;
    for (const x of words) if (x === w) count++;
    if (count > bestCount || (count === bestCount && w < best)) {
      best = w;
      bestCount = count;
    }
  }
  return best;
}

Hints

Hint 1

How many times is each word counted?

Hint 2

One pass with a hash map from word to count, then one pass over the map.

Make it faster

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(n) · Space O(d) for d distinct words

Why it is slow: for each of the n words the inner loop scans all n words, so the work is n^2: 2.5 billion comparisons for 50,000 words, although there are only a few hundred distinct words.

The fix: count every word once into a hash map (O(n)), then pick the best entry from the map (O(distinct words)), breaking ties alphabetically.

Optimized solution

function mostFrequentWord(words) {
  const counts = new Map();
  for (const w of words) counts.set(w, (counts.get(w) ?? 0) + 1);
  let best = null;
  let bestCount = 0;
  for (const [w, c] of counts) {
    if (c > bestCount || (c === bestCount && w < best)) {
      best = w;
      bestCount = c;
    }
  }
  return best;
}

Common mistakes

  • Sorting the entries just to take the first one: fine for correctness, O(d log d) instead of O(d).
  • Forgetting the alphabetical tie-break.

Follow-up questions

  • Return the top k words (heap of size k, or bucket sort by count).
  • The words arrive as an endless stream: approximate counts with a count-min sketch.