Skip to content

Commit 10b0679

Browse files
committed
feat: add solutions to lc problem: No.0721.Accounts Merge
1 parent 5cfc0ac commit 10b0679

File tree

4 files changed

+309
-6
lines changed

4 files changed

+309
-6
lines changed

solution/0700-0799/0721.Accounts Merge/README.md

+145-3
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,169 @@ accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnyb
3838
<li><code>accounts[i][j]</code>的长度将在<code>[1,30]</code>的范围内。</li>
3939
</ul>
4040

41-
4241
## 解法
4342

4443
<!-- 这里可写通用的实现逻辑 -->
4544

45+
并查集。
46+
47+
模板 1——朴素并查集:
48+
49+
```python
50+
# 初始化,p存储每个点的父节点
51+
p = list(range(n))
52+
53+
# 返回x的祖宗节点
54+
def find(x):
55+
if p[x] != x:
56+
# 路径压缩
57+
p[x] = find(p[x])
58+
return p[x]
59+
60+
# 合并a和b所在的两个集合
61+
p[find(a)] = find(b)
62+
```
63+
64+
模板 2——维护 size 的并查集:
65+
66+
```python
67+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
68+
p = list(range(n))
69+
size = [1] * n
70+
71+
# 返回x的祖宗节点
72+
def find(x):
73+
if p[x] != x:
74+
# 路径压缩
75+
p[x] = find(p[x])
76+
return p[x]
77+
78+
# 合并a和b所在的两个集合
79+
if find(a) != find(b):
80+
size[find(b)] += size[find(a)]
81+
p[find(a)] = find(b)
82+
```
83+
84+
模板 3——维护到祖宗节点距离的并查集:
85+
86+
```python
87+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
88+
p = list(range(n))
89+
d = [0] * n
90+
91+
# 返回x的祖宗节点
92+
def find(x):
93+
if p[x] != x:
94+
t = find(p[x])
95+
d[x] += d[p[x]]
96+
p[x] = t
97+
return p[x]
98+
99+
# 合并a和b所在的两个集合
100+
p[find(a)] = find(b)
101+
d[find(a)] = distance
102+
```
103+
104+
对于本题,初始每个 account 是一个独立的集合。遍历 accounts 列表,若遇到相同的 email,则将两账户进行合并,遍历完毕得到并查集。
105+
106+
接着对每个集合进行中的所有账户邮箱进行合并排序,最后返回账户名称以及对应的邮箱列表。
107+
46108
<!-- tabs:start -->
47109

48110
### **Python3**
49111

50112
<!-- 这里可写当前语言的特殊实现逻辑 -->
51113

52114
```python
53-
115+
class Solution:
116+
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
117+
n = len(accounts)
118+
p = list(range(n))
119+
120+
def find(x):
121+
if p[x] != x:
122+
p[x] = find(p[x])
123+
return p[x]
124+
125+
email_id = {}
126+
for i in range(n):
127+
name = accounts[i][0]
128+
for email in accounts[i][1:]:
129+
if email in email_id:
130+
p[find(i)] = find(email_id[email])
131+
else:
132+
email_id[email] = i
133+
134+
mp = collections.defaultdict(set)
135+
for i in range(n):
136+
pa = find(i)
137+
for email in accounts[i][1:]:
138+
mp[pa].add(email)
139+
res = []
140+
for i, emails in mp.items():
141+
t = [accounts[i][0]]
142+
t.extend(sorted(emails))
143+
res.append(t)
144+
return res
54145
```
55146

56147
### **Java**
57148

58149
<!-- 这里可写当前语言的特殊实现逻辑 -->
59150

60151
```java
61-
152+
class Solution {
153+
private int[] p;
154+
155+
public List<List<String>> accountsMerge(List<List<String>> accounts) {
156+
int n = accounts.size();
157+
p = new int[n];
158+
for (int i = 0; i < n; ++i) {
159+
p[i] = i;
160+
}
161+
Map<String, Integer> emailId = new HashMap<>();
162+
for (int i = 0; i < n; ++i) {
163+
List<String> account = accounts.get(i);
164+
String name = account.get(0);
165+
for (int j = 1; j < account.size(); ++j) {
166+
String email = account.get(j);
167+
if (emailId.containsKey(email)) {
168+
p[find(i)] = find(emailId.get(email));
169+
} else {
170+
emailId.put(email, i);
171+
}
172+
}
173+
}
174+
Map<Integer, Set<String>> mp = new HashMap<>();
175+
for (int i = 0; i < n; ++i) {
176+
int pa = find(i);
177+
List<String> account = accounts.get(i);
178+
for (int j = 1; j < account.size(); ++j) {
179+
String email = account.get(j);
180+
if (!mp.containsKey(pa)) {
181+
mp.put(pa, new HashSet<>());
182+
}
183+
mp.get(pa).add(email);
184+
}
185+
}
186+
List<List<String>> res = new ArrayList<>();
187+
for (Map.Entry<Integer, Set<String>> entry : mp.entrySet()) {
188+
List<String> t = new LinkedList<>();
189+
t.addAll(entry.getValue());
190+
Collections.sort(t);
191+
t.add(0, accounts.get(entry.getKey()).get(0));
192+
res.add(t);
193+
}
194+
return res;
195+
}
196+
197+
private int find(int x) {
198+
if (p[x] != x) {
199+
p[x] = find(p[x]);
200+
}
201+
return p[x];
202+
}
203+
}
62204
```
63205

64206
### **...**

solution/0700-0799/0721.Accounts Merge/README_EN.md

+82-3
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,100 @@ We could return these lists in any order, for example the answer [[&#39;Mary&#39
4141
<li><code>accounts[i][j] (for j &gt; 0)</code> is a valid email.</li>
4242
</ul>
4343

44-
4544
## Solutions
4645

4746
<!-- tabs:start -->
4847

4948
### **Python3**
5049

5150
```python
52-
51+
class Solution:
52+
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
53+
n = len(accounts)
54+
p = list(range(n))
55+
56+
def find(x):
57+
if p[x] != x:
58+
p[x] = find(p[x])
59+
return p[x]
60+
61+
email_id = {}
62+
for i in range(n):
63+
name = accounts[i][0]
64+
for email in accounts[i][1:]:
65+
if email in email_id:
66+
p[find(i)] = find(email_id[email])
67+
else:
68+
email_id[email] = i
69+
70+
mp = collections.defaultdict(set)
71+
for i in range(n):
72+
pa = find(i)
73+
for email in accounts[i][1:]:
74+
mp[pa].add(email)
75+
res = []
76+
for i, emails in mp.items():
77+
t = [accounts[i][0]]
78+
t.extend(sorted(emails))
79+
res.append(t)
80+
return res
5381
```
5482

5583
### **Java**
5684

5785
```java
58-
86+
class Solution {
87+
private int[] p;
88+
89+
public List<List<String>> accountsMerge(List<List<String>> accounts) {
90+
int n = accounts.size();
91+
p = new int[n];
92+
for (int i = 0; i < n; ++i) {
93+
p[i] = i;
94+
}
95+
Map<String, Integer> emailId = new HashMap<>();
96+
for (int i = 0; i < n; ++i) {
97+
List<String> account = accounts.get(i);
98+
String name = account.get(0);
99+
for (int j = 1; j < account.size(); ++j) {
100+
String email = account.get(j);
101+
if (emailId.containsKey(email)) {
102+
p[find(i)] = find(emailId.get(email));
103+
} else {
104+
emailId.put(email, i);
105+
}
106+
}
107+
}
108+
Map<Integer, Set<String>> mp = new HashMap<>();
109+
for (int i = 0; i < n; ++i) {
110+
int pa = find(i);
111+
List<String> account = accounts.get(i);
112+
for (int j = 1; j < account.size(); ++j) {
113+
String email = account.get(j);
114+
if (!mp.containsKey(pa)) {
115+
mp.put(pa, new HashSet<>());
116+
}
117+
mp.get(pa).add(email);
118+
}
119+
}
120+
List<List<String>> res = new ArrayList<>();
121+
for (Map.Entry<Integer, Set<String>> entry : mp.entrySet()) {
122+
List<String> t = new LinkedList<>();
123+
t.addAll(entry.getValue());
124+
Collections.sort(t);
125+
t.add(0, accounts.get(entry.getKey()).get(0));
126+
res.add(t);
127+
}
128+
return res;
129+
}
130+
131+
private int find(int x) {
132+
if (p[x] != x) {
133+
p[x] = find(p[x]);
134+
}
135+
return p[x];
136+
}
137+
}
59138
```
60139

61140
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
class Solution {
2+
private int[] p;
3+
4+
public List<List<String>> accountsMerge(List<List<String>> accounts) {
5+
int n = accounts.size();
6+
p = new int[n];
7+
for (int i = 0; i < n; ++i) {
8+
p[i] = i;
9+
}
10+
Map<String, Integer> emailId = new HashMap<>();
11+
for (int i = 0; i < n; ++i) {
12+
List<String> account = accounts.get(i);
13+
String name = account.get(0);
14+
for (int j = 1; j < account.size(); ++j) {
15+
String email = account.get(j);
16+
if (emailId.containsKey(email)) {
17+
p[find(i)] = find(emailId.get(email));
18+
} else {
19+
emailId.put(email, i);
20+
}
21+
}
22+
}
23+
Map<Integer, Set<String>> mp = new HashMap<>();
24+
for (int i = 0; i < n; ++i) {
25+
int pa = find(i);
26+
List<String> account = accounts.get(i);
27+
for (int j = 1; j < account.size(); ++j) {
28+
String email = account.get(j);
29+
if (!mp.containsKey(pa)) {
30+
mp.put(pa, new HashSet<>());
31+
}
32+
mp.get(pa).add(email);
33+
}
34+
}
35+
List<List<String>> res = new ArrayList<>();
36+
for (Map.Entry<Integer, Set<String>> entry : mp.entrySet()) {
37+
List<String> t = new LinkedList<>();
38+
t.addAll(entry.getValue());
39+
Collections.sort(t);
40+
t.add(0, accounts.get(entry.getKey()).get(0));
41+
res.add(t);
42+
}
43+
return res;
44+
}
45+
46+
private int find(int x) {
47+
if (p[x] != x) {
48+
p[x] = find(p[x]);
49+
}
50+
return p[x];
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution:
2+
def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
3+
n = len(accounts)
4+
p = list(range(n))
5+
6+
def find(x):
7+
if p[x] != x:
8+
p[x] = find(p[x])
9+
return p[x]
10+
11+
email_id = {}
12+
for i in range(n):
13+
name = accounts[i][0]
14+
for email in accounts[i][1:]:
15+
if email in email_id:
16+
p[find(i)] = find(email_id[email])
17+
else:
18+
email_id[email] = i
19+
20+
mp = collections.defaultdict(set)
21+
for i in range(n):
22+
pa = find(i)
23+
for email in accounts[i][1:]:
24+
mp[pa].add(email)
25+
res = []
26+
for i, emails in mp.items():
27+
t = [accounts[i][0]]
28+
t.extend(sorted(emails))
29+
res.append(t)
30+
return res

0 commit comments

Comments
 (0)