Skip to content

Commit 176627a

Browse files
committed
feat: add solutions to lc/lcof2 problem: Is Graph Bipartite
1 parent ce5b3c2 commit 176627a

File tree

11 files changed

+625
-6
lines changed

11 files changed

+625
-6
lines changed

lcof2/剑指 Offer II 106. 二分图/README.md

+166-1
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,187 @@
6262

6363
<!-- 这里可写通用的实现逻辑 -->
6464

65+
并查集。
66+
67+
并查集模板:
68+
69+
模板 1——朴素并查集:
70+
71+
```python
72+
# 初始化,p存储每个点的父节点
73+
p = list(range(n))
74+
75+
# 返回x的祖宗节点
76+
def find(x):
77+
if p[x] != x:
78+
# 路径压缩
79+
p[x] = find(p[x])
80+
return p[x]
81+
82+
# 合并a和b所在的两个集合
83+
p[find(a)] = find(b)
84+
```
85+
86+
模板 2——维护 size 的并查集:
87+
88+
```python
89+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
90+
p = list(range(n))
91+
size = [1] * n
92+
93+
# 返回x的祖宗节点
94+
def find(x):
95+
if p[x] != x:
96+
# 路径压缩
97+
p[x] = find(p[x])
98+
return p[x]
99+
100+
# 合并a和b所在的两个集合
101+
if find(a) != find(b):
102+
size[find(b)] += size[find(a)]
103+
p[find(a)] = find(b)
104+
```
105+
106+
模板 3——维护到祖宗节点距离的并查集:
107+
108+
```python
109+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
110+
p = list(range(n))
111+
d = [0] * n
112+
113+
# 返回x的祖宗节点
114+
def find(x):
115+
if p[x] != x:
116+
t = find(p[x])
117+
d[x] += d[p[x]]
118+
p[x] = t
119+
return p[x]
120+
121+
# 合并a和b所在的两个集合
122+
p[find(a)] = find(b)
123+
d[find(a)] = distance
124+
```
125+
126+
对于本题,如果是二分图,那么图中每个顶点的所有邻接点都应该属于同一集合,且不与顶点处于同一集合,因此我们可以使用并查集。遍历图中每个顶点,如果发现存在当前顶点与对应的邻接点处于同一个集合,说明不是二分图。否则将当前节点的邻接点相互进行合并。
127+
65128
<!-- tabs:start -->
66129

67130
### **Python3**
68131

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

71134
```python
72-
135+
class Solution:
136+
def isBipartite(self, graph: List[List[int]]) -> bool:
137+
n = len(graph)
138+
p = list(range(n))
139+
140+
def find(x):
141+
if p[x] != x:
142+
p[x] = find(p[x])
143+
return p[x]
144+
145+
for u, g in enumerate(graph):
146+
for v in g:
147+
if find(u) == find(v):
148+
return False
149+
p[find(v)] = find(g[0])
150+
return True
73151
```
74152

75153
### **Java**
76154

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

79157
```java
158+
class Solution {
159+
private int[] p;
160+
161+
public boolean isBipartite(int[][] graph) {
162+
int n = graph.length;
163+
p = new int[n];
164+
for (int i = 0; i < n; ++i) {
165+
p[i] = i;
166+
}
167+
for (int u = 0; u < n; ++u) {
168+
int[] g = graph[u];
169+
for (int v : g) {
170+
if (find(u) == find(v)) {
171+
return false;
172+
}
173+
p[find(v)] = find(g[0]);
174+
}
175+
}
176+
return true;
177+
}
178+
179+
private int find(int x) {
180+
if (p[x] != x) {
181+
p[x] = find(p[x]);
182+
}
183+
return p[x];
184+
}
185+
}
186+
```
187+
188+
### **C++**
189+
190+
```cpp
191+
class Solution {
192+
public:
193+
vector<int> p;
194+
195+
bool isBipartite(vector<vector<int>>& graph) {
196+
int n = graph.size();
197+
p.resize(n);
198+
for (int i = 0; i < n; ++i) p[i] = i;
199+
for (int u = 0; u < n; ++u)
200+
{
201+
auto g = graph[u];
202+
for (int v : g)
203+
{
204+
if (find(u) == find(v)) return false;
205+
p[find(v)] = find(g[0]);
206+
}
207+
}
208+
return true;
209+
}
210+
211+
int find(int x) {
212+
if (p[x] != x) p[x] = find(p[x]);
213+
return p[x];
214+
}
215+
};
216+
```
80217
218+
### **Go**
219+
220+
```go
221+
var p []int
222+
223+
func isBipartite(graph [][]int) bool {
224+
n := len(graph)
225+
p = make([]int, n)
226+
for i := 0; i < n; i++ {
227+
p[i] = i
228+
}
229+
for u, g := range graph {
230+
for _, v := range g {
231+
if find(u) == find(v) {
232+
return false
233+
}
234+
p[find(v)] = find(g[0])
235+
}
236+
}
237+
return true
238+
}
239+
240+
func find(x int) int {
241+
if p[x] != x {
242+
p[x] = find(p[x])
243+
}
244+
return p[x]
245+
}
81246
```
82247

83248
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
public:
3+
vector<int> p;
4+
5+
bool isBipartite(vector<vector<int>>& graph) {
6+
int n = graph.size();
7+
p.resize(n);
8+
for (int i = 0; i < n; ++i) p[i] = i;
9+
for (int u = 0; u < n; ++u)
10+
{
11+
auto g = graph[u];
12+
for (int v : g)
13+
{
14+
if (find(u) == find(v)) return false;
15+
p[find(v)] = find(g[0]);
16+
}
17+
}
18+
return true;
19+
}
20+
21+
int find(int x) {
22+
if (p[x] != x) p[x] = find(p[x]);
23+
return p[x];
24+
}
25+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
var p []int
2+
3+
func isBipartite(graph [][]int) bool {
4+
n := len(graph)
5+
p = make([]int, n)
6+
for i := 0; i < n; i++ {
7+
p[i] = i
8+
}
9+
for u, g := range graph {
10+
for _, v := range g {
11+
if find(u) == find(v) {
12+
return false
13+
}
14+
p[find(v)] = find(g[0])
15+
}
16+
}
17+
return true
18+
}
19+
20+
func find(x int) int {
21+
if p[x] != x {
22+
p[x] = find(p[x])
23+
}
24+
return p[x]
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
private int[] p;
3+
4+
public boolean isBipartite(int[][] graph) {
5+
int n = graph.length;
6+
p = new int[n];
7+
for (int i = 0; i < n; ++i) {
8+
p[i] = i;
9+
}
10+
for (int u = 0; u < n; ++u) {
11+
int[] g = graph[u];
12+
for (int v : g) {
13+
if (find(u) == find(v)) {
14+
return false;
15+
}
16+
p[find(v)] = find(g[0]);
17+
}
18+
}
19+
return true;
20+
}
21+
22+
private int find(int x) {
23+
if (p[x] != x) {
24+
p[x] = find(p[x]);
25+
}
26+
return p[x];
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def isBipartite(self, graph: List[List[int]]) -> bool:
3+
n = len(graph)
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+
for u, g in enumerate(graph):
12+
for v in g:
13+
if find(u) == find(v):
14+
return False
15+
p[find(v)] = find(g[0])
16+
return True

0 commit comments

Comments
 (0)