-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathGroups of Strings.py
67 lines (58 loc) · 2.09 KB
/
Groups of Strings.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
class DSU:
def __init__(self, n):
self.root = list(range(n))
def find(self, x):
if self.root[x] != x:
self.root[x] = self.find(self.root[x])
return self.root[x]
def union(self, x, y):
self.root[self.find(x)] = self.find(y)
class Solution:
def groupStrings(self, A: List[str]) -> List[int]:
c = collections.defaultdict(int)
for a in A:
c["".join(sorted(a))] += 1
A = list(set(["".join(sorted(a)) for a in A]))
n = len(A)
idx = collections.defaultdict(int) # (binary representation -> index)
dsu = DSU(n) # dsu
def add(base):
for i in range(26):
if not base & 1 << i:
yield base ^ 1 << i
def dele(base):
for i in range(26):
if base & 1 << i:
if base - (1 << i) != 0:
yield base - (1 << i)
def rep(base):
pre, new = [], []
for i in range(26):
if base & 1 << i: pre.append(i)
else: new.append(i)
for p in pre:
for n in new:
yield base - (1 << p) + (1 << n)
for i, a in enumerate(A):
base = 0
for ch in a:
base += 1 << ord(ch) - ord('a')
idx[base] = i
for base in idx.keys():
for new in add(base):
if new in idx:
dsu.union(idx[base], idx[new])
for new in dele(base):
if new in idx:
dsu.union(idx[base], idx[new])
for new in rep(base):
if new in idx:
dsu.union(idx[base], idx[new])
group = collections.defaultdict(int)
for a in A:
base = 0
for ch in a:
base += 1 << ord(ch) - ord('a')
cnum = c[a]
group[dsu.find(idx[base])] += cnum
return [len(group), max(group.values())]