Skip to main content

49. Group Anagrams

mediumAsked at Elastic

Group a list of strings so that anagrams appear together. This is a canonical Elastic question — the sorted-string or frequency-vector canonical key pattern is exactly the normalization step Elasticsearch's token filters apply before building the inverted index.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Elastic loops.

  • Glassdoor (2025-12)Elastic SWE candidates report grouping and normalization problems appearing in mid-level coding rounds.
  • Blind (2025-10)Group Anagrams cited in Elastic interview prep threads as a strong signal question for understanding hashing and canonical forms.

Problem

Given an array of strings strs, group the anagrams together. You can return the answer in any order. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Constraints

  • 1 <= strs.length <= 10^4
  • 0 <= strs[i].length <= 100
  • strs[i] consists of lowercase English letters.

Examples

Example 1

Input
strs = ["eat","tea","tan","ate","nat","bat"]
Output
[["bat"],["nat","tan"],["ate","eat","tea"]]

Explanation: eat/tea/ate are anagrams; tan/nat are anagrams; bat stands alone.

Example 2

Input
strs = [""]
Output
[[""]]

Explanation: Single empty string, one group.

Example 3

Input
strs = ["a"]
Output
[["a"]]

Explanation: Single character, one group.

Approaches

1. Sorted string as key

Sort each string's characters to produce a canonical key. Group strings that share the same canonical key using a Map.

Time
O(n * k log k) where k = max string length
Space
O(n * k)
function groupAnagrams(strs) {
  const map = new Map();
  for (const s of strs) {
    const key = s.split('').sort().join('');
    if (!map.has(key)) map.set(key, []);
    map.get(key).push(s);
  }
  return Array.from(map.values());
}

Tradeoff: Simple and correct. O(n * k log k) due to sorting each string. Acceptable for k <= 100.

2. Frequency vector as key

Represent each string as a 26-element character frequency array. Serialize it to a string key. Avoids sorting entirely.

Time
O(n * k)
Space
O(n * k)
function groupAnagrams(strs) {
  const map = new Map();
  for (const s of strs) {
    const freq = new Array(26).fill(0);
    for (const ch of s) freq[ch.charCodeAt(0) - 97]++;
    const key = freq.join(',');
    if (!map.has(key)) map.set(key, []);
    map.get(key).push(s);
  }
  return Array.from(map.values());
}

Tradeoff: O(n * k) — faster than sorting for long strings. The key is 26 integers joined by commas (length 51 max for single-digit counts). For very long strings with large k, this approach wins.

Elastic-specific tips

Mention both approaches and explain the trade-off: sorting is O(k log k) per string, while the frequency vector is O(k) — so for large k, the frequency vector wins. Elastic's stack processes large token vocabularies, so demonstrating this awareness scores points. Also connect to Elasticsearch's token normalization: 'Elasticsearch applies a similar canonical form when it lowercases and stems tokens before building the inverted index — different surface forms map to the same indexed term.'

Common mistakes

  • Using object keys instead of Map — object key order is not guaranteed and prototype properties can collide.
  • Not initializing the map entry before pushing — always check if the key exists and initialize to [] first.
  • Using the original string as a key — two different anagrams have different string values; you need the canonical form.
  • Forgetting to return Array.from(map.values()) — map.values() returns an iterator, not an array.

Follow-up questions

An interviewer at Elastic may pivot to one of these next:

  • Group Shifted Strings (LC 249) — group strings that are shifts of each other (e.g., 'abc' and 'bcd').
  • How would you group anagrams in a stream without storing all strings in memory?
  • Minimum number of steps to make two strings anagrams (LC 1347).

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why is joining freq with commas better than joining without separator?

Without a separator, freq [1,2,10] serializes to '12010' which collides with [12,0,10]. The comma separator makes each count unambiguous.

What if strings contain uppercase or non-ASCII characters?

The constraints specify lowercase English letters only. For a general solution, use a Map keyed by a character-frequency Map, or sort Unicode code points.

Practice these live with InterviewChamp.AI

Drill Group Anagrams and other Elastic interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →