-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathm0049.py
72 lines (55 loc) · 1.8 KB
/
m0049.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""group anagrams
TAG: hash-table
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.
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"]]
Constraints:
* 1 <= strs.length <= 10^4
* 0 <= strs[i].length <= 100
* strs[i] consists of lower-case English letters.
"""
from collections import defaultdict
from typing import DefaultDict, NamedTuple, Sequence, Tuple
class Middleware(NamedTuple):
array: Tuple[str, ...]
word: str
class Anagram:
@staticmethod
def add_id(word: str) -> Middleware:
return Middleware(tuple(sorted(word)), word)
@staticmethod
def ingest(mws: Sequence[Middleware]) -> DefaultDict:
dd = defaultdict(set)
for _, mw in enumerate(mws):
dd[mw.array].add(mw.word)
return dd
def solution(self, strs: Sequence[str]) -> Sequence[Sequence[str]]:
mw_seq = tuple(self.add_id(word) for word in strs)
dd = self.ingest(mw_seq)
return tuple(sorted(tuple(sorted(t[1])) for t in dd.items()))
if __name__ == '__main__':
ipt_1 = ["eat", "tea", "tan", "ate", "nat", "bat"]
opt_1 = (
("ate", "eat", "tea"),
("bat", ),
("nat", "tan"),
)
ipt_2 = [""]
opt_2 = (("", ), )
ipt_3 = ["a"]
opt_3 = (("a", ), )
anagram = Anagram()
assert anagram.add_id("eat") == Middleware(('a', 'e', 't'), 'eat')
assert anagram.solution(ipt_1) == opt_1
assert anagram.solution(ipt_2) == opt_2
assert anagram.solution(ipt_3) == opt_3