Skip to content

Commit 85ea441

Browse files
author
lifeiyang
committed
2022-11-22-17:07:25
1 parent a6c8e32 commit 85ea441

9 files changed

+424
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from typing import List
2+
3+
4+
# leetcode submit region begin(Prohibit modification and deletion)
5+
class Solution:
6+
def solve(self, board: List[List[str]]) -> None:
7+
"""
8+
Do not return anything, modify board in-place instead.
9+
"""
10+
m, n = len(board), len(board[0])
11+
self.extra_o = [[False for _ in range(n)] for _ in range(m)]
12+
for i in range(m):
13+
for j in [0, n - 1]:
14+
if board[i][j] == "O" and not self.extra_o[i][j]:
15+
# 为 "O" + 没有访问过 + 不是额外的 O
16+
self.traverse(board, i, j)
17+
18+
for j in range(n):
19+
for i in [0, m - 1]:
20+
if board[i][j] == "O" and not self.extra_o[i][j]:
21+
# 为 "O" + 没有访问过 + 不是额外的 O
22+
self.traverse(board, i, j)
23+
24+
# board 中将 self.extra_o 的位置给填上
25+
for i in range(m):
26+
for j in range(n):
27+
if board[i][j] == "O" and not self.extra_o[i][j]:
28+
# board 内是 O,但是 extra_o 内是 False
29+
board[i][j] = "X"
30+
31+
def traverse(self, board, i, j):
32+
if self.extra_o[i][j]:
33+
return
34+
self.extra_o[i][j] = True
35+
if i - 1 >= 0 and board[i - 1][j] == "O":
36+
self.traverse(board, i - 1, j)
37+
38+
if i + 1 <= len(board) - 1 and board[i + 1][j] == "O":
39+
self.traverse(board, i + 1, j)
40+
41+
if j - 1 >= 0 and board[i][j - 1] == "O":
42+
self.traverse(board, i, j - 1)
43+
44+
if j + 1 <= len(board[0]) - 1 and board[i][j + 1] == "O":
45+
self.traverse(board, i, j + 1)
46+
47+
48+
# leetcode submit region end(Prohibit modification and deletion)
49+
50+
if __name__ == "__main__":
51+
solution = Solution()
52+
board = [["O", "O"], ["O", "O"]]
53+
solution.solve(board)
54+
print(board)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from typing import List
2+
3+
4+
# leetcode submit region begin(Prohibit modification and deletion)
5+
class Solution:
6+
def isBipartite(self, graph: List[List[int]]) -> bool:
7+
# 第一个点在 0 侧,第一个点的邻居应该在 1 侧
8+
self.flag = True
9+
# 主要是这里,需要考虑
10+
for idx in range(len(graph)):
11+
self.visited = [False] * len(graph)
12+
self.node_side = {idx: 0}
13+
self.bfs(graph, idx)
14+
return self.flag
15+
16+
def traverse(self, graph, node_idx):
17+
self.visited[node_idx] = True
18+
19+
for neighbor in graph[node_idx]:
20+
if not self.visited[neighbor]:
21+
# 没有访问过
22+
self.node_side[neighbor] = 1 - self.node_side[node_idx]
23+
self.traverse(graph, neighbor)
24+
elif self.node_side[neighbor] == self.node_side[node_idx]:
25+
self.flag = False
26+
27+
def bfs(self, graph, node_idx):
28+
self.visited[node_idx] = True
29+
q = [node_idx]
30+
while len(q) > 0:
31+
cur = q.pop(0)
32+
for neighbor in graph[cur]:
33+
if not self.visited[neighbor]:
34+
self.node_side[neighbor] = 1 - self.node_side[cur]
35+
self.visited[neighbor] = True
36+
q.append(neighbor)
37+
elif self.node_side[neighbor] == self.node_side[cur]:
38+
self.flag = False
39+
return
40+
41+
42+
# leetcode submit region end(Prohibit modification and deletion)
43+
44+
45+
if __name__ == "__main__":
46+
solution = Solution()
47+
print(solution.isBipartite(
48+
[[], [2, 4, 6], [1, 4, 8, 9], [7, 8], [1, 2, 8, 9], [6, 9], [1, 5, 7, 8, 9], [3, 6, 9], [2, 3, 4, 6, 9],
49+
[2, 4, 5, 6, 7, 8]]), False)
50+
print(solution.isBipartite([[], [3], [], [1], []]), True)
51+
print(solution.isBipartite([[1, 2, 3], [0, 2], [0, 1, 3], [0, 2]]), False)
52+
print(solution.isBipartite([[1, 3], [0, 2], [1, 3], [0, 2]]), True)
53+
print(solution.isBipartite([[0]]), False)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from typing import List
2+
3+
4+
# leetcode submit region begin(Prohibit modification and deletion)
5+
class Solution:
6+
def possibleBipartition(self, n: int, dislikes: List[List[int]]) -> bool:
7+
graph = self.build_graph(dislikes)
8+
self.visited = [False] * n
9+
self.flag = True
10+
11+
for node_idx in range(n):
12+
if not self.visited[node_idx]:
13+
self.node_side = {node_idx: 0}
14+
self.traverse(graph, node_idx)
15+
16+
return self.flag
17+
18+
def traverse(self, graph, node_idx):
19+
self.visited[node_idx] = True
20+
for neighbor in graph[node_idx]:
21+
if not self.visited[neighbor]:
22+
# 没有访问过
23+
self.node_side[neighbor] = 1 - self.node_side[node_idx]
24+
self.traverse(graph, neighbor)
25+
elif self.node_side[neighbor] != 1 - self.node_side[node_idx]:
26+
# 访问过,但是节点关系不正确
27+
self.flag = False
28+
29+
def build_graph(self, dislikes):
30+
from collections import defaultdict
31+
graph = defaultdict(list)
32+
for pair in dislikes:
33+
graph[pair[0] - 1].append(pair[1] - 1)
34+
graph[pair[1] - 1].append(pair[0] - 1)
35+
return graph
36+
37+
38+
# leetcode submit region end(Prohibit modification and deletion)
39+
40+
if __name__ == "__main__":
41+
solution = Solution()
42+
print(solution.possibleBipartition(4, [[1, 2], [1, 3], [2, 4]]), True)
43+
print(solution.possibleBipartition(3, [[1, 2], [1, 3], [2, 3]]), False)
44+
print(solution.possibleBipartition(5, [[1, 2], [2, 3], [3, 4], [4, 5], [1, 5]]), False)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from typing import List
2+
3+
4+
# leetcode submit region begin(Prohibit modification and deletion)
5+
class UnionFind:
6+
def __init__(self, char_list):
7+
self.parent = {}
8+
for char in char_list:
9+
self.parent[char] = char
10+
11+
def connect(self, char1, char2):
12+
char1_root = self.find_parent(char1)
13+
char2_root = self.find_parent(char2)
14+
15+
self.parent[char1_root] = char2_root
16+
17+
def find_parent(self, char):
18+
if self.parent[char] != char:
19+
self.parent[char] = self.find_parent(self.parent[char])
20+
return self.parent[char]
21+
22+
def is_connect(self, char1, char2):
23+
char1_parent = self.find_parent(char1)
24+
char2_parent = self.find_parent(char2)
25+
return char1_parent == char2_parent
26+
27+
28+
class Solution:
29+
def equationsPossible(self, equations: List[str]) -> bool:
30+
char_set = set()
31+
32+
for pair in equations:
33+
char_set.add(pair[0])
34+
char_set.add(pair[-1])
35+
uf = UnionFind(list(char_set))
36+
37+
# 构造关系
38+
for pair in equations:
39+
if "==" in pair:
40+
uf.connect(pair[0], pair[-1])
41+
42+
# 开始验证
43+
flag = True
44+
for pair in equations:
45+
if "!=" in pair:
46+
if uf.is_connect(pair[0], pair[-1]):
47+
flag = False
48+
return flag
49+
50+
51+
# leetcode submit region end(Prohibit modification and deletion)
52+
53+
if __name__ == "__main__":
54+
solution = Solution()
55+
print(solution.equationsPossible(["a==b", "b!=c", "c==a"]), False)
56+
print(solution.equationsPossible(["e==e", "d!=e", "c==d", "d!=e"]), True)
57+
print(solution.equationsPossible(["e!=c", "b!=b", "b!=a", "e==d"]), False)
58+
print(solution.equationsPossible(["a!=a"]), False)
59+
print(solution.equationsPossible(["a==a"]), True)
60+
print(solution.equationsPossible(["a==b"]), True)
61+
print(solution.equationsPossible(["a!=b"]), True)
62+
print(solution.equationsPossible(["a==b", "b!=a"]), False)
63+
print(solution.equationsPossible(["b==a", "a==b"]), True)
64+
print(solution.equationsPossible(["a==b", "b==c", "a==c"]), True)
65+
print(solution.equationsPossible(["c==c", "b==d", "x!=z"]), True)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
给你一个 <code>m x n</code> 的矩阵 <code>board</code> ,由若干字符 <code>'X'</code> 和 <code>'O'</code> ,找到所有被 <code>'X'</code> 围绕的区域,并将这些区域里所有的 <code>'O'</code> 用 <code>'X'</code> 填充。
2+
3+
<div class="original__bRMd">
4+
<div>
5+
<p>&nbsp;</p>
6+
</div>
7+
</div>
8+
9+
<p><strong>示例 1:</strong></p>
10+
<img alt="" src="https://assets.leetcode.com/uploads/2021/02/19/xogrid.jpg" style="width: 550px; height: 237px;" />
11+
<pre>
12+
<strong>输入:</strong>board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
13+
<strong>输出:</strong>[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
14+
<strong>解释:</strong>被围绕的区间不会存在于边界上,换句话说,任何边界上的&nbsp;<span><code>'O'</code></span>&nbsp;都不会被填充为&nbsp;<span><code>'X'</code></span>。 任何不在边界上,或不与边界上的&nbsp;<span><code>'O'</code></span>&nbsp;相连的&nbsp;<span><code>'O'</code></span>&nbsp;最终都会被填充为&nbsp;<span><code>'X'</code></span>。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
15+
</pre>
16+
17+
<p><strong>示例 2:</strong></p>
18+
19+
<pre>
20+
<strong>输入:</strong>board = [["X"]]
21+
<strong>输出:</strong>[["X"]]
22+
</pre>
23+
24+
<p>&nbsp;</p>
25+
26+
<p><strong>提示:</strong></p>
27+
28+
<ul>
29+
<li><code>m == board.length</code></li>
30+
<li><code>n == board[i].length</code></li>
31+
<li><code>1 &lt;= m, n &lt;= 200</code></li>
32+
<li><code>board[i][j]</code> 为 <code>'X'</code> 或 <code>'O'</code></li>
33+
</ul>
34+
35+
<div><div>Related Topics</div><div><li>深度优先搜索</li><li>广度优先搜索</li><li>并查集</li><li>数组</li><li>矩阵</li></div></div><br><div><li>👍 893</li><li>👎 0</li></div>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
存在一个 <strong>无向图</strong> ,图中有 <code>n</code> 个节点。其中每个节点都有一个介于 <code>0</code> 到 <code>n - 1</code> 之间的唯一编号。给你一个二维数组 <code>graph</code> ,其中 <code>graph[u]</code> 是一个节点数组,由节点 <code>u</code> 的邻接节点组成。形式上,对于 <code>graph[u]</code> 中的每个 <code>v</code> ,都存在一条位于节点 <code>u</code> 和节点 <code>v</code> 之间的无向边。该无向图同时具有以下属性:
2+
3+
<ul>
4+
<li>不存在自环(<code>graph[u]</code> 不包含 <code>u</code>)。</li>
5+
<li>不存在平行边(<code>graph[u]</code> 不包含重复值)。</li>
6+
<li>如果 <code>v</code> 在 <code>graph[u]</code> 内,那么 <code>u</code> 也应该在 <code>graph[v]</code> 内(该图是无向图)</li>
7+
<li>这个图可能不是连通图,也就是说两个节点 <code>u</code> 和 <code>v</code> 之间可能不存在一条连通彼此的路径。</li>
8+
</ul>
9+
10+
<p><strong>二分图</strong> 定义:如果能将一个图的节点集合分割成两个独立的子集 <code>A</code> 和 <code>B</code> ,并使图中的每一条边的两个节点一个来自 <code>A</code> 集合,一个来自 <code>B</code> 集合,就将这个图称为 <strong>二分图</strong> 。</p>
11+
12+
<p>如果图是二分图,返回 <code>true</code><em> </em>;否则,返回 <code>false</code> 。</p>
13+
14+
<p>&nbsp;</p>
15+
16+
<p><strong>示例 1:</strong></p>
17+
<img alt="" src="https://assets.leetcode.com/uploads/2020/10/21/bi2.jpg" style="width: 222px; height: 222px;" />
18+
<pre>
19+
<strong>输入:</strong>graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
20+
<strong>输出:</strong>false
21+
<strong>解释:</strong><span><code>不能将节点分割成两个独立的子集,</code></span>以使每条边都连通一个子集中的一个节点与另一个子集中的一个节点。</pre>
22+
23+
<p><strong>示例 2:</strong></p>
24+
<img alt="" src="https://assets.leetcode.com/uploads/2020/10/21/bi1.jpg" style="width: 222px; height: 222px;" />
25+
<pre>
26+
<strong>输入:</strong>graph = [[1,3],[0,2],[1,3],[0,2]]
27+
<strong>输出:</strong>true
28+
<strong>解释:</strong><span><code>可以将节点分成两组: {0, 2} 和 {1, 3} 。</code></span></pre>
29+
30+
<p>&nbsp;</p>
31+
32+
<p><strong>提示:</strong></p>
33+
34+
<ul>
35+
<li><code>graph.length == n</code></li>
36+
<li><code>1 &lt;= n &lt;= 100</code></li>
37+
<li><code>0 &lt;= graph[u].length &lt; n</code></li>
38+
<li><code>0 &lt;= graph[u][i] &lt;= n - 1</code></li>
39+
<li><code>graph[u]</code> 不会包含 <code>u</code></li>
40+
<li><code>graph[u]</code> 的所有值 <strong>互不相同</strong></li>
41+
<li>如果 <code>graph[u]</code> 包含 <code>v</code>,那么 <code>graph[v]</code> 也会包含 <code>u</code></li>
42+
</ul>
43+
44+
<div><div>Related Topics</div><div><li>深度优先搜索</li><li>广度优先搜索</li><li>并查集</li><li>图</li></div></div><br><div><li>👍 424</li><li>👎 0</li></div>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<p>给定一组&nbsp;<code>n</code>&nbsp;人(编号为&nbsp;<code>1, 2, ..., n</code>),&nbsp;我们想把每个人分进<strong>任意</strong>大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。</p>
2+
3+
<p>给定整数 <code>n</code>&nbsp;和数组 <code>dislikes</code>&nbsp;,其中&nbsp;<code>dislikes[i] = [a<sub>i</sub>, b<sub>i</sub>]</code>&nbsp;,表示不允许将编号为 <code>a<sub>i</sub></code>&nbsp;&nbsp;&nbsp;<code>b<sub>i</sub></code>的人归入同一组。当可以用这种方法将所有人分进两组时,返回 <code>true</code>;否则返回 <code>false</code>。</p>
4+
5+
<p>&nbsp;</p>
6+
7+
<ol>
8+
</ol>
9+
10+
<p><strong>示例 1:</strong></p>
11+
12+
<pre>
13+
<strong>输入:</strong>n = 4, dislikes = [[1,2],[1,3],[2,4]]
14+
<strong>输出:</strong>true
15+
<strong>解释:</strong>group1 [1,4], group2 [2,3]
16+
</pre>
17+
18+
<p><strong>示例 2:</strong></p>
19+
20+
<pre>
21+
<strong>输入:</strong>n = 3, dislikes = [[1,2],[1,3],[2,3]]
22+
<strong>输出:</strong>false
23+
</pre>
24+
25+
<p><strong>示例 3:</strong></p>
26+
27+
<pre>
28+
<strong>输入:</strong>n = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
29+
<strong>输出:</strong>false
30+
</pre>
31+
32+
<p>&nbsp;</p>
33+
34+
<p><strong>提示:</strong></p>
35+
36+
<ul>
37+
<li><code>1 &lt;= n &lt;= 2000</code></li>
38+
<li><code>0 &lt;= dislikes.length &lt;= 10<sup>4</sup></code></li>
39+
<li><code>dislikes[i].length == 2</code></li>
40+
<li><code>1 &lt;= dislikes[i][j] &lt;= n</code></li>
41+
<li><code>a<sub>i</sub>&nbsp;&lt; b<sub>i</sub></code></li>
42+
<li><code>dislikes</code>&nbsp;中每一组都 <strong>不同</strong></li>
43+
</ul>
44+
45+
<p>&nbsp;</p>
46+
47+
<div><div>Related Topics</div><div><li>深度优先搜索</li><li>广度优先搜索</li><li>并查集</li><li>图</li></div></div><br><div><li>👍 349</li><li>👎 0</li></div>

0 commit comments

Comments
 (0)