all entries
A-004Day 042026.05.07mediumleetcode #49neetcode150

Group Anagrams

#array#hash-table#string#sorting
leetcode #49 · group-anagrams
01

Problem

· problem
P.004

Group Anagrams

leetcode #49

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

constraints
  • · 1 ≤ strs.length ≤ 10^4
  • · 0 ≤ strs[i].length ≤ 100
  • · strs[i] consists of lowercase English letters
// paraphrased summary — see source for full text
examples
example 1input → output
["eat","tea","tan","ate","nat","bat"]
[["eat","tea","ate"],["tan","nat"],["bat"]]
example 2input → output
[""]
[[""]]
example 3input → output
["a"]
[["a"]]
02

Pre-solve

· pre-solve
● 1list shown● 2select● 3reveal
  • What makes two strings anagrams of each other?
  • How can we create a unique signature that identifies all anagrams of a string?
  • Which data structure allows us to group strings by a shared signature efficiently?
  • Does the order of groups in the output matter?
  • Is it necessary to sort the input array before processing?
  • Must each group's strings be sorted before returning?
  • Can we use sorted strings as keys instead of character frequencies?
check the items you would ask, then press confirm
// session-only state — refresh resets (repeatable practice)
03

Logic Structure

· logic
● 1slots shown● 2pick per slot● 3reveal
// pick one code line per slot to assemble the algorithm flow. no typing — just the logic skeleton.
step 1· Initialize result dictionary
groups = {}
groups = collections.defaultdict(list)
groups = []
step 2· Iterate through each string
for s in strs: # O(m)
for i in range(len(strs)): s = strs[i]
for s in strs[::-1]:
step 3· Count character frequenciesnested
count[char] = count.get(char, 0) + 1
count[char] += 1
count[char] = 1
step 4· Create canonical key from countsnested
tup = tuple(sorted(count.items())) # O(1) because there is limited amount of possible keys in the alphabet -> O(26) + O(26*log26) + O(26)
tup = sorted(count.items())
tup = tuple(count.keys())
step 5· Add string to groupnested
groups[tup].append(s)
groups[tup] = [s]
groups.append((tup, s))
step 6· Return grouped results
return list(groups.values())
return groups
return list(groups.keys())
pick one option per slot
// format: slot — recursive / DP patterns use ordering / state-first formats. ADR-08 follow-up.
04

Solve · Trace

· solve
solution.py
1
class Solution:
2
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
3
        groups = {}
4
5
        # Iterate over strings
6
        for s in strs: # O(m)
7
            count = {}
8
9
            # Count frequency of each character
10
            for char in s: # O(n)
11
                count[char] = count.get(char, 0) + 1
12
13
            # Convert count Dict to List, sort it, and then convert to Tuple (we cannot use dicts or lists as keys in a hashmap)
14
            tup = tuple(sorted(count.items())) # O(1) because there is limited amount of possible keys in the alphabet -> O(26) + O(26*log26) + O(26)
15
16
            if tup in groups:
17
                groups[tup].append(s)
18
            else:
19
                groups[tup] = [s] 
20
            
21
        return list(groups.values())
22
    
23
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
24
        ans = collections.defaultdict(list)
25
26
        for s in strs:
27
            count = [0] * 26
28
            for c in s:
29
                count[ord(c) - ord("a")] += 1
30
            ans[tuple(count)].append(s)
31
        return list(ans.values())
mental dry-run cases
// walk each case in your head; expand the worked example below if stuck.
case 1
["eat","tea","tan","ate","nat","bat"]
[["eat","tea","ate"],["tan","nat"],["bat"]]
case 2
[""]
[[""]]
case 3
["a"]
[["a"]]
// UI does not walk-through — you do the dry-run mentally. Expand the worked example if stuck.