Example
Input: accounts = [["John","johnsmith@mail.com","john_newyork@mail.com"],
["John","johnsmith@mail.com","john00@mail.com"],
["Mary","mary@mail.com"],["John","johnnybravo@mail.com"]]
Output: [["John","john00@mail.com","john_newyork@mail.com","johnsmith@mail.com"],
["Mary","mary@mail.com"],
["John","johnnybravo@mail.com"]]
TC: O(NKlogNK)
SC: O(NK)
class UnionFind:
def __init__(self, n):
self.parent = {i:i for i in range(n)}
self.rank = [0 for _ in range(n)]
def union(self, u, v):
par_u, par_v = self.find(u), self.find(v)
if par_u == par_v:
return
if self.rank[par_u] < self.rank[par_v]:
self.parent[par_u] = par_v
elif self.rank[par_u] > self.rank[par_v]:
self.parent[par_v] = par_u
else:
self.parent[par_u] = par_v
self.rank[par_v] += 1
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
n = len(accounts)
uf = UnionFind(n)
email_group = {}
for i in range(n):
account_size = len(accounts[i])
for j in range(1, account_size):
email = accounts[i][j]
if email not in email_group:
email_group[email] = i
else:
uf.union(i, email_group[email])
group_emails_dict = defaultdict(list)
for email, group in email_group.items():
group_parent = uf.find(group)
group_emails_dict[group_parent].append(email)
accounts_merged = []
for group, emails in group_emails_dict.items():
name = accounts[group][0]
accounts_merged.append([name] + sorted(emails))
return accounts_merged