721. 账户合并
方法一:暴力
class Solution:
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
if not accounts:
return
lookup = defaultdict(list)
res = []
for account in accounts:
name = account[0]
email = set(account[1:])
lookup[name].append(email)
for e in lookup[name][:-1]:
if e & email:
lookup[name].remove(e)
lookup[name][-1].update(e)
for key, val in lookup.items():
for tmp in val:
res.append([key] + list(sorted(tmp)))
return res
方法二:dfs
class Solution:
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
graph = defaultdict(set)
email_to_name = defaultdict()
for account in accounts:
name, emails = account[0], account[1:]
for email in emails:
email_to_name[email] = name
graph[emails[0]].add(email)
graph[email].add(emails[0])
visited = set()
res = []
def dfs(e):
new_list.append(e)
for t in graph[e]:
if t not in visited:
visited.add(t)
dfs(t)
for e in graph:
if e not in visited:
visited.add(e)
new_list = []
dfs(e)
res.append([email_to_name[e]] + sorted(new_list))
return res
方法三:bfs
class Solution:
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
graph = defaultdict(set)
email_to_name = defaultdict()
for account in accounts:
name, emails = account[0], account[1:]
for email in emails:
email_to_name[email] = name
graph[emails[0]].add(email)
graph[email].add(emails[0])
visited = set()
res = []
def bfs(e):
ans = []
stack = deque()
stack.appendleft(e)
while stack:
tmp = stack.pop()
ans.append(tmp)
for t in graph[tmp]:
if t not in visited:
visited.add(t)
stack.appendleft(t)
return ans
for e in graph:
if e not in visited:
visited.add(e)
ans = bfs(e)
res.append([email_to_name[e]] + sorted(ans))
return res
方法四:并查集
class Solution:
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
f = {}
def find(x):
f.setdefault(x, x)
while f[x] != x:
f[x] = f[f[x]]
x = f[x]
return x
def union(x, y):
f[find(x)] = find(y)
lookup = {}
n = len(accounts)
for idx, account in enumerate(accounts):
name, email = account[0], account[1:]
for e in email:
if e in lookup:
union(idx, lookup[e])
else:
lookup[e] = idx
disJoinSet = defaultdict(set)
for i in range(n):
tmp = find(i)
for es in accounts[i][1:]:
disJoinSet[tmp].add(es)
res = []
for key, val in disJoinSet.items():
res.append([accounts[key][0]] + list(sorted(val)))
return res