Skip to content

Commit 436e258

Browse files
committed
feat: add solutions to lc problem: No.0261.Graph Valid Tree
1 parent 14ab2f5 commit 436e258

File tree

6 files changed

+343
-4
lines changed

6 files changed

+343
-4
lines changed

solution/0200-0299/0261.Graph Valid Tree/README.md

+152-2
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,177 @@
2020

2121
<p><strong>注意:</strong>你可以假定边列表 <code>edges</code> 中不会出现重复的边。由于所有的边是无向边,边&nbsp;<code>[0,1]</code>&nbsp;和边 <code>[1,0]</code>&nbsp;是相同的,因此不会同时出现在边列表 <code>edges</code> 中。</p>
2222

23-
2423
## 解法
2524

2625
<!-- 这里可写通用的实现逻辑 -->
2726

27+
并查集模板题。
28+
29+
模板 1——朴素并查集:
30+
31+
```python
32+
# 初始化,p存储每个点的祖宗节点
33+
p = [i for i in range(n)]
34+
# 返回x的祖宗节点
35+
def find(x):
36+
if p[x] != x:
37+
# 路径压缩
38+
p[x] = find(p[x])
39+
return p[x]
40+
# 合并a和b所在的两个集合
41+
p[find(a)] = find(b)
42+
```
43+
44+
模板 2——维护 size 的并查集:
45+
46+
```python
47+
# 初始化,p存储每个点的祖宗节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
48+
p = [i for i in range(n)]
49+
size = [1] * n
50+
# 返回x的祖宗节点
51+
def find(x):
52+
if p[x] != x:
53+
# 路径压缩
54+
p[x] = find(p[x])
55+
return p[x]
56+
# 合并a和b所在的两个集合
57+
size[find(b)] += size[find(a)]
58+
p[find(a)] = find(b)
59+
```
60+
61+
模板 3——维护到祖宗节点距离的并查集:
62+
63+
```python
64+
# 初始化,p存储每个点的祖宗节点,d[x]存储x到p[x]的距离
65+
p = [i for i in range(n)]
66+
d = [0] * n
67+
# 返回x的祖宗节点
68+
def find(x):
69+
if p[x] != x:
70+
t = find(p[x])
71+
d[x] += d[p[x]]
72+
p[x] = t
73+
return p[x]
74+
# 合并a和b所在的两个集合
75+
p[find(a)] = find(b)
76+
d[find(a)] = dinstance
77+
```
78+
79+
2880
<!-- tabs:start -->
2981

3082
### **Python3**
3183

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

3486
```python
35-
87+
class Solution:
88+
def validTree(self, n: int, edges: List[List[int]]) -> bool:
89+
p = list(range(n))
90+
91+
def find(x):
92+
if p[x] != x:
93+
p[x] = find(p[x])
94+
return p[x]
95+
96+
for a, b in edges:
97+
if find(a) == find(b):
98+
return False
99+
p[find(a)] = find(b)
100+
n -= 1
101+
return n == 1
36102
```
37103

38104
### **Java**
39105

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

42108
```java
109+
class Solution {
110+
private int[] p;
111+
112+
public boolean validTree(int n, int[][] edges) {
113+
p = new int[n];
114+
for (int i = 0; i < n; ++i) {
115+
p[i] = i;
116+
}
117+
for (int[] e : edges) {
118+
if (find(e[0]) == find(e[1])) {
119+
return false;
120+
}
121+
p[find(e[0])] = find(e[1]);
122+
--n;
123+
}
124+
return n == 1;
125+
}
126+
127+
private int find(int x) {
128+
if (p[x] != x) {
129+
p[x] = find(p[x]);
130+
}
131+
return p[x];
132+
}
133+
}
134+
```
135+
136+
### **C++**
137+
138+
```cpp
139+
class Solution {
140+
public:
141+
vector<int> p;
142+
143+
bool validTree(int n, vector<vector<int>> &edges) {
144+
for (int i = 0; i < n; ++i)
145+
{
146+
p.push_back(i);
147+
}
148+
for (auto e : edges)
149+
{
150+
if (find(e[0]) == find(e[1]))
151+
return false;
152+
p[find(e[0])] = find(e[1]);
153+
--n;
154+
}
155+
return n == 1;
156+
}
157+
158+
int find(int x) {
159+
if (p[x] != x)
160+
{
161+
p[x] = find(p[x]);
162+
}
163+
return p[x];
164+
}
165+
};
166+
```
43167

168+
### **Go**
169+
170+
```go
171+
var p []int
172+
173+
func validTree(n int, edges [][]int) bool {
174+
p = make([]int, n)
175+
for i := 0; i < n; i++ {
176+
p[i] = i
177+
}
178+
for _, e := range edges {
179+
if find(e[0]) == find(e[1]) {
180+
return false
181+
}
182+
p[find(e[0])] = find(e[1])
183+
n--
184+
}
185+
return n == 1
186+
}
187+
188+
func find(x int) int {
189+
if p[x] != x {
190+
p[x] = find(p[x])
191+
}
192+
return p[x]
193+
}
44194
```
45195

46196
### **...**

solution/0200-0299/0261.Graph Valid Tree/README_EN.md

+101-2
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,120 @@
3535
<li>There are no self-loops or repeated edges.</li>
3636
</ul>
3737

38-
3938
## Solutions
4039

40+
Union find.
41+
4142
<!-- tabs:start -->
4243

4344
### **Python3**
4445

4546
```python
46-
47+
class Solution:
48+
def validTree(self, n: int, edges: List[List[int]]) -> bool:
49+
p = list(range(n))
50+
51+
def find(x):
52+
if p[x] != x:
53+
p[x] = find(p[x])
54+
return p[x]
55+
56+
for a, b in edges:
57+
if find(a) == find(b):
58+
return False
59+
p[find(a)] = find(b)
60+
n -= 1
61+
return n == 1
4762
```
4863

4964
### **Java**
5065

5166
```java
67+
class Solution {
68+
private int[] p;
69+
70+
public boolean validTree(int n, int[][] edges) {
71+
p = new int[n];
72+
for (int i = 0; i < n; ++i) {
73+
p[i] = i;
74+
}
75+
for (int[] e : edges) {
76+
if (find(e[0]) == find(e[1])) {
77+
return false;
78+
}
79+
p[find(e[0])] = find(e[1]);
80+
--n;
81+
}
82+
return n == 1;
83+
}
84+
85+
private int find(int x) {
86+
if (p[x] != x) {
87+
p[x] = find(p[x]);
88+
}
89+
return p[x];
90+
}
91+
}
92+
```
93+
94+
### **C++**
95+
96+
```cpp
97+
class Solution {
98+
public:
99+
vector<int> p;
100+
101+
bool validTree(int n, vector<vector<int>> &edges) {
102+
for (int i = 0; i < n; ++i)
103+
{
104+
p.push_back(i);
105+
}
106+
for (auto e : edges)
107+
{
108+
if (find(e[0]) == find(e[1]))
109+
return false;
110+
p[find(e[0])] = find(e[1]);
111+
--n;
112+
}
113+
return n == 1;
114+
}
115+
116+
int find(int x) {
117+
if (p[x] != x)
118+
{
119+
p[x] = find(p[x]);
120+
}
121+
return p[x];
122+
}
123+
};
124+
```
52125

126+
### **Go**
127+
128+
```go
129+
var p []int
130+
131+
func validTree(n int, edges [][]int) bool {
132+
p = make([]int, n)
133+
for i := 0; i < n; i++ {
134+
p[i] = i
135+
}
136+
for _, e := range edges {
137+
if find(e[0]) == find(e[1]) {
138+
return false
139+
}
140+
p[find(e[0])] = find(e[1])
141+
n--
142+
}
143+
return n == 1
144+
}
145+
146+
func find(x int) int {
147+
if p[x] != x {
148+
p[x] = find(p[x])
149+
}
150+
return p[x]
151+
}
53152
```
54153

55154
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
vector<int> p;
4+
5+
bool validTree(int n, vector<vector<int>> &edges) {
6+
for (int i = 0; i < n; ++i)
7+
{
8+
p.push_back(i);
9+
}
10+
for (auto e : edges)
11+
{
12+
if (find(e[0]) == find(e[1]))
13+
return false;
14+
p[find(e[0])] = find(e[1]);
15+
--n;
16+
}
17+
return n == 1;
18+
}
19+
20+
int find(int x) {
21+
if (p[x] != x)
22+
{
23+
p[x] = find(p[x]);
24+
}
25+
return p[x];
26+
}
27+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var p []int
2+
3+
func validTree(n int, edges [][]int) bool {
4+
p = make([]int, n)
5+
for i := 0; i < n; i++ {
6+
p[i] = i
7+
}
8+
for _, e := range edges {
9+
if find(e[0]) == find(e[1]) {
10+
return false
11+
}
12+
p[find(e[0])] = find(e[1])
13+
n--
14+
}
15+
return n == 1
16+
}
17+
18+
func find(x int) int {
19+
if p[x] != x {
20+
p[x] = find(p[x])
21+
}
22+
return p[x]
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
private int[] p;
3+
4+
public boolean validTree(int n, int[][] edges) {
5+
p = new int[n];
6+
for (int i = 0; i < n; ++i) {
7+
p[i] = i;
8+
}
9+
for (int[] e : edges) {
10+
if (find(e[0]) == find(e[1])) {
11+
return false;
12+
}
13+
p[find(e[0])] = find(e[1]);
14+
--n;
15+
}
16+
return n == 1;
17+
}
18+
19+
private int find(int x) {
20+
if (p[x] != x) {
21+
p[x] = find(p[x]);
22+
}
23+
return p[x];
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution:
2+
def validTree(self, n: int, edges: List[List[int]]) -> bool:
3+
p = list(range(n))
4+
5+
def find(x):
6+
if p[x] != x:
7+
p[x] = find(p[x])
8+
return p[x]
9+
10+
for a, b in edges:
11+
if find(a) == find(b):
12+
return False
13+
p[find(a)] = find(b)
14+
n -= 1
15+
return n == 1

0 commit comments

Comments
 (0)