Skip to main content

49. Group Anagrams

mediumAsked at JPMorgan

Group an array of strings such that strings that are anagrams of one another sit together. JPMorgan asks this on SDE onsites to test whether you choose the right canonical key (sorted string vs character-count tuple) and reason about the tradeoffs.

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

Source citations

Public interview reports confirming this problem appears in JPMorgan loops.

  • Glassdoor (2026-Q1)JPMorgan SDE onsite reports cite this as a recurring hash-map design problem.
  • LeetCode (2026-Q1)Tagged JPMorgan on the LeetCode company tag page.
  • Blind (2025-11)JPMC SWE-II write-up: 'asked group anagrams, then asked which canonical key is cheaper'.

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"]]

Example 2

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

Example 3

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

Approaches

1. Sort each string as the key (simple optimal)

Use the sorted version of each string as a hash-map key; group originals into buckets keyed by it.

Time
O(n * k log k) where k is 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: Easiest to read and ship. The k log k sort dominates per string — fine for k <= 100 but slower than the counting key on long strings.

2. Character-count signature as the key (asymptotic optimal)

Build a 26-slot frequency array for each string and use its string form as the map key.

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

Tradeoff: Asymptotically tighter — strict O(k) per string instead of O(k log k). Worth using on the LeetCode constraint when strings are long; otherwise the sort version is one line shorter and equally fast in practice.

JPMorgan-specific tips

JPMorgan interviewers ask 'which key is cheaper?' after you write the sort version. The expected answer: the 26-slot counting signature is O(k) per string instead of O(k log k), and avoids the per-string allocation a sort would do — meaningful when k is large or the input is the hot path in a service. Most candidates write the sort version and stop, leaving the asymptotic win on the table.

Common mistakes

  • Using an array of arrays as a key (Map keys are reference-equal for arrays — every key looks unique).
  • Forgetting to convert the count array to a string before using it as a key.
  • Sorting in place with strs[i].split('').sort() and forgetting that strings are immutable — works in JS but trips up developers from languages where it does not.
  • Returning the map keys instead of the values.

Follow-up questions

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

  • Valid Anagram (LC 242) — single-pair version of this same idea.
  • Group shifted strings (LC 249).
  • Find all anagrams in a string (LC 438) — sliding-window with the count signature.
  • What if the alphabet was Unicode rather than lowercase English?

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 the character-count signature asymptotically faster?

Sorting a string of length k costs O(k log k) comparisons. Counting characters into a 26-slot array is O(k) — strictly faster for any k > some small constant. On LeetCode where k can be 100, the constant factors usually make sort competitive, but on a 10000-character string the counting version wins clearly.

What if the strings contain Unicode?

The 26-slot count array no longer fits. Use a Map<codepoint, count> per string and serialise it deterministically (sort by codepoint, join). The sort-based approach scales without modification but is slower; the counting approach generalises with the extra serialisation step.

Free learning resources

Curated free links for this problem.

Practice these live with InterviewChamp.AI

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

Practice these live with InterviewChamp.AI →