Skip to content

Commit f9c501d

Browse files
committed
feat: add solutions to lcof2 problem: No.116,118
1 parent 7b96117 commit f9c501d

File tree

10 files changed

+580
-1
lines changed

10 files changed

+580
-1
lines changed

Diff for: lcof2/剑指 Offer II 116. 朋友圈/README.md

+232
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,254 @@
5252

5353
<!-- 这里可写通用的实现逻辑 -->
5454

55+
**方法一:深度优先搜索**
56+
57+
判断城市之间是否属于同一个连通分量,最后连通分量的总数即为结果。
58+
59+
**方法二:并查集**
60+
61+
模板 1——朴素并查集:
62+
63+
```python
64+
# 初始化,p存储每个点的祖宗节点
65+
p = [i for i in range(n)]
66+
# 返回x的祖宗节点
67+
def find(x):
68+
if p[x] != x:
69+
# 路径压缩
70+
p[x] = find(p[x])
71+
return p[x]
72+
# 合并a和b所在的两个集合
73+
p[find(a)] = find(b)
74+
```
75+
76+
模板 2——维护 size 的并查集:
77+
78+
```python
79+
# 初始化,p存储每个点的祖宗节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
80+
p = [i for i in range(n)]
81+
size = [1] * n
82+
# 返回x的祖宗节点
83+
def find(x):
84+
if p[x] != x:
85+
# 路径压缩
86+
p[x] = find(p[x])
87+
return p[x]
88+
# 合并a和b所在的两个集合
89+
size[find(b)] += size[find(a)]
90+
p[find(a)] = find(b)
91+
```
92+
93+
模板 3——维护到祖宗节点距离的并查集:
94+
95+
```python
96+
# 初始化,p存储每个点的祖宗节点,d[x]存储x到p[x]的距离
97+
p = [i for i in range(n)]
98+
d = [0] * n
99+
# 返回x的祖宗节点
100+
def find(x):
101+
if p[x] != x:
102+
t = find(p[x])
103+
d[x] += d[p[x]]
104+
p[x] = t
105+
return p[x]
106+
# 合并a和b所在的两个集合
107+
p[find(a)] = find(b)
108+
d[find(a)] = dinstance
109+
```
110+
55111
<!-- tabs:start -->
56112

57113
### **Python3**
58114

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

117+
深度优先搜索:
118+
61119
```python
120+
class Solution:
121+
def findCircleNum(self, isConnected: List[List[int]]) -> int:
122+
def dfs(i):
123+
for j in range(n):
124+
if not visited[j] and isConnected[i][j] == 1:
125+
visited[j] = True
126+
dfs(j)
62127

128+
n = len(isConnected)
129+
visited = [False] * n
130+
num = 0
131+
for i in range(n):
132+
if not visited[i]:
133+
dfs(i)
134+
num += 1
135+
return num
136+
```
137+
138+
并查集:
139+
140+
```python
141+
class Solution:
142+
def findCircleNum(self, isConnected: List[List[int]]) -> int:
143+
n = len(isConnected)
144+
p = [i for i in range(n)]
145+
146+
def find(x):
147+
if p[x] != x:
148+
p[x] = find(p[x])
149+
return p[x]
150+
151+
for i in range(n):
152+
for j in range(n):
153+
if i != j and isConnected[i][j] == 1:
154+
p[find(i)] = find(j)
155+
return sum(i == find(i) for i in range(n))
63156
```
64157

65158
### **Java**
66159

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

162+
深度优先搜索:
163+
69164
```java
165+
class Solution {
166+
public int findCircleNum(int[][] isConnected) {
167+
int n = isConnected.length;
168+
boolean[] visited = new boolean[n];
169+
int num = 0;
170+
for (int i = 0; i < n; ++i) {
171+
if (!visited[i]) {
172+
dfs(isConnected, visited, i, n);
173+
++num;
174+
}
175+
}
176+
return num;
177+
}
178+
179+
private void dfs(int[][] isConnected, boolean[] visited, int i, int n) {
180+
for (int j = 0; j < n; ++j) {
181+
if (!visited[j] && isConnected[i][j] == 1) {
182+
visited[j] = true;
183+
dfs(isConnected, visited, j, n);
184+
}
185+
}
186+
}
187+
}
188+
```
189+
190+
并查集:
191+
192+
```java
193+
class Solution {
194+
private int[] p;
195+
196+
public int findCircleNum(int[][] isConnected) {
197+
int n = isConnected.length;
198+
p = new int[n];
199+
for (int i = 0; i < n; ++i) {
200+
p[i] = i;
201+
}
202+
for (int i = 0; i < n; ++i) {
203+
for (int j = 0; j < n; ++j) {
204+
if (isConnected[i][j] == 1) {
205+
p[find(i)] = find(j);
206+
}
207+
}
208+
}
209+
int cnt = 0;
210+
for (int i = 0; i < n; ++i) {
211+
if (i == find(i)) {
212+
++cnt;
213+
}
214+
}
215+
return cnt;
216+
}
217+
218+
private int find(int x) {
219+
if (p[x] != x) {
220+
p[x] = find(p[x]);
221+
}
222+
return p[x];
223+
}
224+
}
225+
```
226+
227+
### **C++**
228+
229+
```cpp
230+
class Solution {
231+
public:
232+
vector<int> p;
233+
234+
int findCircleNum(vector<vector<int>> &isConnected) {
235+
int n = isConnected.size();
236+
p.resize(n);
237+
for (int i = 0; i < n; ++i)
238+
{
239+
p[i] = i;
240+
}
241+
for (int i = 0; i < n; ++i)
242+
{
243+
for (int j = 0; j < n; ++j)
244+
{
245+
if (isConnected[i][j])
246+
{
247+
p[find(i)] = find(j);
248+
}
249+
}
250+
}
251+
int cnt = 0;
252+
for (int i = 0; i < n; ++i)
253+
{
254+
if (i == find(i))
255+
++cnt;
256+
}
257+
return cnt;
258+
}
259+
260+
int find(int x) {
261+
if (p[x] != x)
262+
{
263+
p[x] = find(p[x]);
264+
}
265+
return p[x];
266+
}
267+
};
268+
```
269+
270+
### **Go**
271+
272+
```go
273+
var p []int
274+
275+
func findCircleNum(isConnected [][]int) int {
276+
n := len(isConnected)
277+
p = make([]int, n)
278+
for i := 1; i < n; i++ {
279+
p[i] = i
280+
}
281+
for i := 0; i < n; i++ {
282+
for j := 0; j < n; j++ {
283+
if isConnected[i][j] == 1 {
284+
p[find(i)] = find(j)
285+
}
286+
}
287+
}
288+
cnt := 0
289+
for i := 0; i < n; i++ {
290+
if i == find(i) {
291+
cnt++
292+
}
293+
}
294+
return cnt
295+
}
70296

297+
func find(x int) int {
298+
if p[x] != x {
299+
p[x] = find(p[x])
300+
}
301+
return p[x]
302+
}
71303
```
72304

73305
### **...**

Diff for: lcof2/剑指 Offer II 116. 朋友圈/Solution.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
public:
3+
vector<int> p;
4+
5+
int findCircleNum(vector<vector<int>> &isConnected) {
6+
int n = isConnected.size();
7+
p.resize(n);
8+
for (int i = 0; i < n; ++i)
9+
{
10+
p[i] = i;
11+
}
12+
for (int i = 0; i < n; ++i)
13+
{
14+
for (int j = 0; j < n; ++j)
15+
{
16+
if (isConnected[i][j])
17+
{
18+
p[find(i)] = find(j);
19+
}
20+
}
21+
}
22+
int cnt = 0;
23+
for (int i = 0; i < n; ++i)
24+
{
25+
if (i == find(i))
26+
++cnt;
27+
}
28+
return cnt;
29+
}
30+
31+
int find(int x) {
32+
if (p[x] != x)
33+
{
34+
p[x] = find(p[x]);
35+
}
36+
return p[x];
37+
}
38+
};

Diff for: lcof2/剑指 Offer II 116. 朋友圈/Solution.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
var p []int
2+
3+
func findCircleNum(isConnected [][]int) int {
4+
n := len(isConnected)
5+
p = make([]int, n)
6+
for i := 1; i < n; i++ {
7+
p[i] = i
8+
}
9+
for i := 0; i < n; i++ {
10+
for j := 0; j < n; j++ {
11+
if isConnected[i][j] == 1 {
12+
p[find(i)] = find(j)
13+
}
14+
}
15+
}
16+
cnt := 0
17+
for i := 0; i < n; i++ {
18+
if i == find(i) {
19+
cnt++
20+
}
21+
}
22+
return cnt
23+
}
24+
25+
func find(x int) int {
26+
if p[x] != x {
27+
p[x] = find(p[x])
28+
}
29+
return p[x]
30+
}

Diff for: lcof2/剑指 Offer II 116. 朋友圈/Solution.java

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution {
2+
public int findCircleNum(int[][] isConnected) {
3+
int n = isConnected.length;
4+
boolean[] visited = new boolean[n];
5+
int num = 0;
6+
for (int i = 0; i < n; ++i) {
7+
if (!visited[i]) {
8+
dfs(isConnected, visited, i, n);
9+
++num;
10+
}
11+
}
12+
return num;
13+
}
14+
15+
private void dfs(int[][] isConnected, boolean[] visited, int i, int n) {
16+
for (int j = 0; j < n; ++j) {
17+
if (!visited[j] && isConnected[i][j] == 1) {
18+
visited[j] = true;
19+
dfs(isConnected, visited, j, n);
20+
}
21+
}
22+
}
23+
}

Diff for: lcof2/剑指 Offer II 116. 朋友圈/Solution.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def findCircleNum(self, isConnected: List[List[int]]) -> int:
3+
def dfs(i):
4+
for j in range(n):
5+
if not visited[j] and isConnected[i][j] == 1:
6+
visited[j] = True
7+
dfs(j)
8+
9+
n = len(isConnected)
10+
visited = [False] * n
11+
num = 0
12+
for i in range(n):
13+
if not visited[i]:
14+
dfs(i)
15+
num += 1
16+
return num

0 commit comments

Comments
 (0)