Skip to content

Commit 50308b7

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

16 files changed

+680
-12
lines changed

leetcode/editor/cn/[102]二叉树的层序遍历.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,20 @@ def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
2323
queue = []
2424
res = []
2525

26-
queue.append(root)
26+
queue.append([root, 0])
2727

2828
while len(queue) > 0:
29-
temp_res = []
30-
queue_length = len(queue)
31-
# 注意这里的双层循环设计,这样可以将同一层结果使用 temp_res 记录
32-
for i in range(queue_length):
33-
cur = queue.pop(0)
34-
if cur.left is not None:
35-
queue.append(cur.left)
36-
if cur.right is not None:
37-
queue.append(cur.right)
38-
temp_res.append(cur.val)
29+
cur, depth = queue.pop(0)
30+
if cur.left is not None:
31+
queue.append([cur.left, depth + 1])
32+
if cur.right is not None:
33+
queue.append([cur.right, depth + 1])
3934

40-
res.append(temp_res)
35+
# depth 为 0 的时候,res 需要有 1 个长度了
36+
if len(res) == depth:
37+
res.append([cur.val])
38+
else:
39+
res[depth].append(cur.val)
4140

4241
return res
4342

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from typing import List
2+
3+
4+
# leetcode submit region begin(Prohibit modification and deletion)
5+
class Solution:
6+
def maxProbability(self, n: int, edges: List[List[int]], succProb: List[float], start: int, end: int) -> float:
7+
# 权重
8+
weight = {}
9+
for edge, prob in zip(edges, succProb):
10+
weight[tuple([edge[0], edge[1]])] = prob
11+
weight[tuple([edge[1], edge[0]])] = prob
12+
13+
graph = self.build_graph(n, edges)
14+
15+
# 每个点距离 start 的距离, start 本身为 0
16+
distance_to_start = [0] * n
17+
distance_to_start[start] = 1
18+
19+
# 开始 bfs
20+
queue = [[start, 1]]
21+
while len(queue) > 0:
22+
from_node, from_distance = queue.pop(0)
23+
if from_distance < distance_to_start[from_node]:
24+
# 已经有概率更大的实现了
25+
continue
26+
27+
for neighbor_node in graph[from_node]:
28+
if tuple([from_node, neighbor_node]) in weight:
29+
neighbor_distance = distance_to_start[from_node] * weight[tuple([from_node, neighbor_node])]
30+
if distance_to_start[neighbor_node] < neighbor_distance:
31+
distance_to_start[neighbor_node] = neighbor_distance
32+
queue.append([neighbor_node, neighbor_distance])
33+
34+
return distance_to_start[end]
35+
36+
def build_graph(self, n, edges):
37+
graph = [[] for _ in range(n)]
38+
for edge in edges:
39+
from_node, to_node = edge
40+
graph[from_node].append(to_node)
41+
graph[to_node].append(from_node)
42+
return graph
43+
44+
45+
# leetcode submit region end(Prohibit modification and deletion)
46+
47+
48+
if __name__ == "__main__":
49+
solution = Solution()
50+
51+
n = 5
52+
edges = [[1, 4], [2, 4], [0, 4], [0, 3], [0, 2], [2, 3]]
53+
succProb = [0.37, 0.17, 0.93, 0.23, 0.39, 0.04]
54+
start = 3
55+
end = 4
56+
print(solution.maxProbability(n, edges, succProb, start, end), 0.2139)
57+
58+
n = 3
59+
edges = [[0, 1]]
60+
succProb = [0.5]
61+
start = 0
62+
end = 2
63+
print(solution.maxProbability(n, edges, succProb, start, end), 0)
64+
65+
n = 3
66+
edges = [[0, 1], [1, 2], [0, 2]]
67+
succProb = [0.5, 0.5, 0.2]
68+
start = 0
69+
end = 2
70+
71+
print(solution.maxProbability(n, edges, succProb, start, end), 0.25)
72+
73+
n = 3
74+
edges = [[0, 1], [1, 2], [0, 2]]
75+
succProb = [0.5, 0.5, 0.3]
76+
start = 0
77+
end = 2
78+
print(solution.maxProbability(n, edges, succProb, start, end), 0.3)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import math
2+
from typing import List
3+
4+
5+
# leetcode submit region begin(Prohibit modification and deletion)
6+
class Solution:
7+
def minimumEffortPath(self, heights: List[List[int]]) -> int:
8+
m, n = len(heights), len(heights[0])
9+
10+
# 出发点
11+
queue = [[[0, 0], 0]]
12+
distance_from_index = [[math.inf for _ in range(n)] for _ in range(m)]
13+
distance_from_index[0][0] = 0
14+
15+
while len(queue) > 0:
16+
from_node, from_distance = queue.pop(0)
17+
for move in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
18+
neighbor = [from_node[0] + move[0], from_node[1] + move[1]]
19+
if 0 <= neighbor[0] < m and 0 <= neighbor[1] < n:
20+
# 判断是否越界
21+
neighbor_distance = max(
22+
distance_from_index[from_node[0]][from_node[1]],
23+
abs(
24+
heights[from_node[0]][from_node[1]] -
25+
heights[neighbor[0]][neighbor[1]]
26+
)
27+
)
28+
if neighbor_distance < distance_from_index[neighbor[0]][neighbor[1]]:
29+
distance_from_index[neighbor[0]][neighbor[1]] = neighbor_distance
30+
queue.append([neighbor, neighbor_distance])
31+
32+
return distance_from_index[m - 1][n - 1]
33+
34+
35+
# leetcode submit region end(Prohibit modification and deletion)
36+
37+
if __name__ == "__main__":
38+
solution = Solution()
39+
print(solution.minimumEffortPath([[1, 10, 6, 7, 9, 10, 4, 9]]), 9)
40+
print(solution.minimumEffortPath([[1, 2, 2], [3, 8, 2], [5, 3, 5]]), 2)
41+
print(solution.minimumEffortPath(
42+
[[1, 2, 1, 1, 1], [1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 1, 1, 2, 1]]), 0)
43+
print(solution.minimumEffortPath([[1, 2, 3], [3, 8, 4], [5, 3, 5]]), 1)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# leetcode submit region begin(Prohibit modification and deletion)
2+
class Solution:
3+
def strStr(self, haystack: str, needle: str) -> int:
4+
# leetcode submit region end(Prohibit modification and deletion)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import math
2+
from typing import List
3+
4+
5+
# leetcode submit region begin(Prohibit modification and deletion)
6+
class Solution:
7+
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
8+
# 构造 graph 和 边的权重,所有都 - 1
9+
graph = [[] for _ in range(n)]
10+
weight = [[0 for _ in range(n)] for _ in range(n)]
11+
for source_node, target_node, value in times:
12+
graph[source_node - 1].append(target_node - 1)
13+
weight[source_node - 1][target_node - 1] = value
14+
15+
# 一开始距离是无穷远
16+
distance_from_k = [math.inf] * n
17+
18+
# 初始节点
19+
distance_from_k[k - 1] = 0
20+
queue = [[k - 1, 0]]
21+
while len(queue) > 0:
22+
from_node, from_distance = queue.pop(0)
23+
if from_distance > distance_from_k[from_node]:
24+
continue
25+
26+
for neighbor in graph[from_node]:
27+
neighbor_distance = distance_from_k[from_node] + weight[from_node][neighbor]
28+
if neighbor_distance < distance_from_k[neighbor]:
29+
distance_from_k[neighbor] = neighbor_distance
30+
queue.append([neighbor, neighbor_distance])
31+
32+
if math.inf in distance_from_k:
33+
return -1
34+
else:
35+
return max(distance_from_k)
36+
37+
38+
# leetcode submit region end(Prohibit modification and deletion)
39+
40+
if __name__ == "__main__":
41+
solution = Solution()
42+
print(solution.networkDelayTime([[2, 1, 1], [2, 3, 1], [3, 4, 1]], 4, 2), 2)
43+
print(solution.networkDelayTime([[1, 2, 1]], 2, 1), 1)
44+
print(solution.networkDelayTime([[1, 2, 1]], 2, 2), -1)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,60 @@
11
# leetcode submit region begin(Prohibit modification and deletion)
2+
import math
3+
4+
25
class Solution:
6+
37
def minWindow(self, s: str, t: str) -> str:
8+
need_char_2_count = {}
9+
for char in t:
10+
if char not in need_char_2_count:
11+
need_char_2_count[char] = 1
12+
else:
13+
need_char_2_count[char] += 1
14+
15+
left, right = 0, 0
16+
window_char_2_count = {}
17+
valid = 0
18+
19+
window_left, window_len = 0, math.inf
20+
while right < len(s):
21+
22+
# 更新窗口内的数据分布
23+
if s[right] in window_char_2_count:
24+
window_char_2_count[s[right]] += 1
25+
else:
26+
window_char_2_count[s[right]] = 1
27+
28+
if s[right] in need_char_2_count and \
29+
window_char_2_count[s[right]] == need_char_2_count[s[right]]:
30+
valid += 1
31+
32+
right += 1
33+
while valid == len(need_char_2_count):
34+
if right - left < window_len:
35+
window_len = right - left
36+
window_left = left
37+
38+
# 更新窗口内的数据分布
39+
if s[left] in need_char_2_count and \
40+
window_char_2_count[s[left]] == need_char_2_count[s[left]]:
41+
valid -= 1
42+
43+
window_char_2_count[s[left]] -= 1
44+
left += 1
45+
46+
if window_len == math.inf:
47+
return ""
48+
else:
49+
return s[window_left:window_left + window_len]
50+
51+
452
# leetcode submit region end(Prohibit modification and deletion)
53+
54+
55+
if __name__ == "__main__":
56+
solution = Solution()
57+
print(solution.minWindow("ADOBECODEBANC", "ABC"), "BANC")
58+
print(solution.minWindow("aa", "aa"), "aa")
59+
print(solution.minWindow("a", "a"), "a")
60+
print(solution.minWindow("a", "aa"), "")
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<p>给你一个由 <code>n</code> 个节点(下标从 0 开始)组成的无向加权图,该图由一个描述边的列表组成,其中 <code>edges[i] = [a, b]</code> 表示连接节点 a 和 b 的一条无向边,且该边遍历成功的概率为 <code>succProb[i]</code> 。</p>
2+
3+
<p>指定两个节点分别作为起点 <code>start</code> 和终点 <code>end</code> ,请你找出从起点到终点成功概率最大的路径,并返回其成功概率。</p>
4+
5+
<p>如果不存在从 <code>start</code> 到 <code>end</code> 的路径,请 <strong>返回 0</strong> 。只要答案与标准答案的误差不超过 <strong>1e-5 </strong>,就会被视作正确答案。</p>
6+
7+
<p>&nbsp;</p>
8+
9+
<p><strong>示例 1:</strong></p>
10+
11+
<p><strong><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/07/12/1558_ex1.png" style="height: 186px; width: 187px;" /></strong></p>
12+
13+
<pre><strong>输入:</strong>n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
14+
<strong>输出:</strong>0.25000
15+
<strong>解释:</strong>从起点到终点有两条路径,其中一条的成功概率为 0.2 ,而另一条为 0.5 * 0.5 = 0.25
16+
</pre>
17+
18+
<p><strong>示例 2:</strong></p>
19+
20+
<p><strong><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/07/12/1558_ex2.png" style="height: 186px; width: 189px;" /></strong></p>
21+
22+
<pre><strong>输入:</strong>n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
23+
<strong>输出:</strong>0.30000
24+
</pre>
25+
26+
<p><strong>示例 3:</strong></p>
27+
28+
<p><strong><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/07/12/1558_ex3.png" style="height: 191px; width: 215px;" /></strong></p>
29+
30+
<pre><strong>输入:</strong>n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
31+
<strong>输出:</strong>0.00000
32+
<strong>解释:</strong>节点 0 和 节点 2 之间不存在路径
33+
</pre>
34+
35+
<p>&nbsp;</p>
36+
37+
<p><strong>提示:</strong></p>
38+
39+
<ul>
40+
<li><code>2 &lt;= n &lt;= 10^4</code></li>
41+
<li><code>0 &lt;= start, end &lt; n</code></li>
42+
<li><code>start != end</code></li>
43+
<li><code>0 &lt;= a, b &lt; n</code></li>
44+
<li><code>a != b</code></li>
45+
<li><code>0 &lt;= succProb.length == edges.length &lt;= 2*10^4</code></li>
46+
<li><code>0 &lt;= succProb[i] &lt;= 1</code></li>
47+
<li>每两个节点之间最多有一条边</li>
48+
</ul>
49+
50+
<div><div>Related Topics</div><div><li>图</li><li>数组</li><li>最短路</li><li>堆(优先队列)</li></div></div><br><div><li>👍 113</li><li>👎 0</li></div>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<p>你准备参加一场远足活动。给你一个二维&nbsp;<code>rows x columns</code>&nbsp;的地图&nbsp;<code>heights</code>&nbsp;,其中&nbsp;<code>heights[row][col]</code>&nbsp;表示格子&nbsp;<code>(row, col)</code>&nbsp;的高度。一开始你在最左上角的格子&nbsp;<code>(0, 0)</code>&nbsp;,且你希望去最右下角的格子&nbsp;<code>(rows-1, columns-1)</code>&nbsp;(注意下标从 <strong>0</strong> 开始编号)。你每次可以往 <strong>上</strong>,<strong>下</strong>,<strong>左</strong>,<strong>右</strong>&nbsp;四个方向之一移动,你想要找到耗费 <strong>体力</strong> 最小的一条路径。</p>
2+
3+
<p>一条路径耗费的 <strong>体力值</strong>&nbsp;是路径上相邻格子之间 <strong>高度差绝对值</strong>&nbsp;的 <strong>最大值</strong>&nbsp;决定的。</p>
4+
5+
<p>请你返回从左上角走到右下角的最小<strong>&nbsp;体力消耗值</strong>&nbsp;。</p>
6+
7+
<p>&nbsp;</p>
8+
9+
<p><strong>示例 1:</strong></p>
10+
11+
<p><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/10/25/ex1.png" style="width: 300px; height: 300px;" /></p>
12+
13+
<pre>
14+
<b>输入:</b>heights = [[1,2,2],[3,8,2],[5,3,5]]
15+
<b>输出:</b>2
16+
<b>解释:</b>路径 [1,3,5,3,5] 连续格子的差值绝对值最大为 2 。
17+
这条路径比路径 [1,2,2,2,5] 更优,因为另一条路径差值最大值为 3 。
18+
</pre>
19+
20+
<p><strong>示例 2:</strong></p>
21+
22+
<p><img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/10/25/ex2.png" style="width: 300px; height: 300px;" /></p>
23+
24+
<pre>
25+
<b>输入:</b>heights = [[1,2,3],[3,8,4],[5,3,5]]
26+
<b>输出:</b>1
27+
<b>解释:</b>路径 [1,2,3,4,5] 的相邻格子差值绝对值最大为 1 ,比路径 [1,3,5,3,5] 更优。
28+
</pre>
29+
30+
<p><strong>示例 3:</strong></p>
31+
<img alt="" src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/10/25/ex3.png" style="width: 300px; height: 300px;" />
32+
<pre>
33+
<b>输入:</b>heights = [[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]
34+
<b>输出:</b>0
35+
<b>解释:</b>上图所示路径不需要消耗任何体力。
36+
</pre>
37+
38+
<p>&nbsp;</p>
39+
40+
<p><strong>提示:</strong></p>
41+
42+
<ul>
43+
<li><code>rows == heights.length</code></li>
44+
<li><code>columns == heights[i].length</code></li>
45+
<li><code>1 &lt;= rows, columns &lt;= 100</code></li>
46+
<li><code>1 &lt;= heights[i][j] &lt;= 10<sup>6</sup></code></li>
47+
</ul>
48+
49+
<div><div>Related Topics</div><div><li>深度优先搜索</li><li>广度优先搜索</li><li>并查集</li><li>数组</li><li>二分查找</li><li>矩阵</li><li>堆(优先队列)</li></div></div><br><div><li>👍 325</li><li>👎 0</li></div>

0 commit comments

Comments
 (0)