|
| 1 | +# [Description](https://leetcode-cn.com/problems/accounts-merge) |
| 2 | +给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该账户的邮箱地址。 |
| 3 | + |
| 4 | +现在,我们想合并这些账户。如果两个账户都有一些共同的邮箱地址,则两个账户必定属于同一个人。请注意,即使两个账户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的账户,但其所有账户都具有相同的名称。 |
| 5 | + |
| 6 | +合并账户后,按以下格式返回账户:每个账户的第一个元素是名称,其余元素是按字符 ASCII 顺序排列的邮箱地址。账户本身可以以任意顺序返回。 |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +示例 1: |
| 11 | +```python |
| 12 | +输入: |
| 13 | + |
| 14 | +输出: |
| 15 | + |
| 16 | +解释: |
| 17 | +第一个和第三个 John 是同一个人,因为他们有共同的邮箱地址 "[email protected]"。 |
| 18 | +第二个 John 和 Mary 是不同的人,因为他们的邮箱地址没有被其他帐户使用。 |
| 19 | +可以以任何顺序返回这些列表,例如答案 [[ 'Mary', '[email protected]'],[ 'John', '[email protected]'], |
| 20 | + |
| 21 | +``` |
| 22 | + |
| 23 | +提示: |
| 24 | + |
| 25 | +- accounts的长度将在[1,1000]的范围内。 |
| 26 | +- accounts[i]的长度将在[1,10]的范围内。 |
| 27 | +- accounts[i][j]的长度将在[1,30]的范围内。 |
| 28 | + |
| 29 | + |
| 30 | +# Solution |
| 31 | +- 本题的不同之处在于,**并查集存储的是每条account的index之间的father关系** |
| 32 | +```python |
| 33 | +class UnionFind: |
| 34 | + def __init__(self, length): |
| 35 | + self.father = [i for i in range(length)] |
| 36 | + self.mail2index = {} |
| 37 | + |
| 38 | + def find(self, x): |
| 39 | + root = x |
| 40 | + |
| 41 | + while self.father[root] != root: |
| 42 | + root = self.father[root] |
| 43 | + |
| 44 | + # 路径压缩 |
| 45 | + while x != root: |
| 46 | + original_father = self.father[x] |
| 47 | + self.father[x] = root |
| 48 | + x = original_father |
| 49 | + |
| 50 | + return root |
| 51 | + |
| 52 | + def merge(self, x, y): |
| 53 | + root_x, root_y = self.find(x), self.find(y) |
| 54 | + |
| 55 | + if root_x != root_y: |
| 56 | + self.father[root_x] = root_y |
| 57 | + |
| 58 | +class Solution: |
| 59 | + def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]: |
| 60 | + uf = UnionFind(len(accounts)) |
| 61 | + index2name = {} |
| 62 | + sets = {} |
| 63 | + |
| 64 | + for i, c in enumerate(accounts): |
| 65 | + index2name[i] = c[0] |
| 66 | + for j in range(1, len(c)): |
| 67 | + mail = c[j] |
| 68 | + if mail in uf.mail2index: |
| 69 | + uf.merge(uf.mail2index[mail], i) |
| 70 | + uf.mail2index[mail] = i |
| 71 | + |
| 72 | + for l, i in enumerate(uf.father): |
| 73 | + index = uf.find(i) |
| 74 | + if index not in sets: sets[index] = set() # 其实这个的set可以使用defaultdict |
| 75 | + sets[index].update(accounts[l]) |
| 76 | + |
| 77 | + res = [] |
| 78 | + for k, v in sets.items(): |
| 79 | + res.append(sorted(list(v))) |
| 80 | + return res |
| 81 | + |
| 82 | +``` |
0 commit comments