Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

‎lcof2/剑指 Offer II 116. 朋友圈/README.md‎

Lines changed: 232 additions & 0 deletions
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
### **...**
Lines changed: 38 additions & 0 deletions
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+
};
Lines changed: 30 additions & 0 deletions
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+
}
Lines changed: 23 additions & 0 deletions
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+
}
Lines changed: 16 additions & 0 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /