题目:

  1. 给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,
  2. 其中第一个元素 accounts[i][0] 名称 (name),其余元素是 emails 表示该帐户的邮箱地址。
  3. 现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,
  4. 则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,
  5. 它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,
  6. 但其所有帐户都具有相同的名称。
  7. 合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,
  8. 其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。
  9. 例子 1:
  10. Input:
  11. accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
  12. Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
  13. Explanation:
  14. 第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 "johnsmith@mail.com"
  15. 第二个 John Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。
  16. 我们可以以任何顺序返回这些列表,例如答案[['Mary''mary@mail.com'],['John''johnnybravo@mail.com'],
  17. ['John''john00@mail.com''john_newyork@mail.com''johnsmith@mail.com']]仍然会被接受。
  18. 来源:力扣(LeetCode
  19. 链接:https://leetcode-cn.com/problems/accounts-merge
  20. 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

答案:

时间:

20min,未果,逻辑错了。

  1. class UnionFind:
  2. def __init__(self,n):
  3. self.parent = [i for i in range(n)]
  4. self.rank = [n-i for i in range(n)]
  5. self.count = n
  6. def find(self,p):
  7. while self.parent[p] != self.parent[self.parent[p]]:
  8. self.parent[p] = self.parent[self.parent[p]]
  9. return self.parent[p]
  10. def union(self,p,q):
  11. i = self.find(p)
  12. j = self.find(q)
  13. if i == j:
  14. return
  15. if self.rank [i] < self.rank [j]:
  16. self.parent[i] = j
  17. self.rank [j] += self.rank [i]
  18. else:
  19. self.parent[j] = i
  20. self.rank [i] += self.rank [j]
  21. self.count -= 1
  22. class Solution:
  23. def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
  24. n=len(accounts)
  25. e2name={}
  26. e2id={}
  27. Email=UnionFind(n)
  28. for i in range(n):
  29. name=accounts[i][0]
  30. post=accounts[i][1:]
  31. for mail in post:
  32. e2name[mail]=name
  33. if mail in e2id:
  34. Email.union(i,e2id[mail])
  35. e2id[mail]= Email.find(i)
  36. else:
  37. e2id[mail]=i
  38. temp=collections.defaultdict(list)
  39. for mail,index in e2id.items():
  40. father=Email.find(index)
  41. temp[father].append(mail)
  42. ans=[]
  43. for k,v in temp.items():
  44. ans.append([accounts[k][0]]+sorted(temp[k]))
  45. return ans

要点:

1. 并查集

如果邮箱曾经出现过,就合并,太妙了,我怎么就没想到

2. 最后还要找一下爹

不然可能还是儿子代打

3. 最后还要满足题意sort一下

4. 谁作为index

这里只有email是可以hash的,所以所有的dict都用email来做为索引去想就可以了

其他:

代码报错:无