LeetCode 62. 不同路徑 | Python
技術標籤:LeetCode動態規劃演算法leetcodepython
62. 不同路徑
題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/unique-paths/
題目
一個機器人位於一個 m x n
網格的左上角 (起始點在下圖中標記為 “Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為 “Finish” )。
問總共有多少條不同的路徑?
示例 1:
圖源來自:力扣(62. 不同路徑)
輸入:m = 3, n = 7
輸出:28
示例 2:
輸入:m = 3, n = 2 輸出:3 解釋: 從左上角開始,總共有 3 條路徑可以到達右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右
示例 3:
輸入:m = 7, n = 3
輸出:28
示例 4:
輸入:m = 3, n = 3
輸出:6
提示:
- 1 ≤ m , n ≤ 100 1 \leq m, n \leq 100 1≤m,n≤100
- 題目資料保證答案小於等於 2 ∗ 1 0 9 2 * 10^{9} 2∗109
解題思路
思路:動態規劃
先審題,題目給定一個 m × n m \times n m×n 的網格,左上角放置一個機器人,右下角為終點,問機器人到達終點的路徑有多少條?
其中機器人的移動規則為:
- 每次只能向下或者向右移動一步。
現在假設
f
(
m
,
n
)
f(m, n)
f(m,n)
f
(
m
,
n
)
=
f
(
m
−
1
,
n
)
+
f
(
m
,
n
−
1
)
f(m, n) = f(m-1, n) + f(m, n-1)
f(m,n)=f(m−1,n)+f(m,n−1)
這裡加上遞迴終止條件,就能夠求得最終的結果。但是這種自底向上的遞迴中間會有大量重複的計算,這裡我們可以將其改為自頂向下的遞推。
狀態定義
設
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 表示到格子
(
i
,
j
)
(i, j)
狀態轉移方程
根據機器人的移動規則【每次只能向下或者向右移動一步】,那麼格子
(
i
,
j
)
(i, j)
(i,j) 可以從格子
(
i
−
1
,
j
)
(i-1, j)
(i−1,j) 或者格子
(
i
,
j
−
1
)
(i, j-1)
(i,j−1) 移動到達。那麼此時的轉移方程為:
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
+
d
p
[
i
]
[
j
−
1
]
dp[i][j] = dp[i-1][j] + dp[i][j-1]
dp[i][j]=dp[i−1][j]+dp[i][j−1]
狀態初始化
由於機器人移動規則限制,第一列的格子只能是由機器人從上往下移動到達,初始化 d p [ i ] [ 0 ] dp[i][0] dp[i][0] 的值為 1。
同樣的第一行的格子,只能是由機器人從左到右移動到達,初始化 d p [ 0 ] [ j ] dp[0][j] dp[0][j] 的值為 1。
最終要求到達網格右下角的總路徑和,那麼最終返回 d p [ m − 1 ] [ n − 1 ] dp[m-1][n-1] dp[m−1][n−1]。
具體的程式碼實現如下。
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[0] * n for _ in range(m)]
# 初始化
for i in range(m):
dp[i][0] = 1
for j in range(n):
dp[0][j] = 1
# 根據轉移方程進行遞推
for i in range(1, m):
for j in range(1, n):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1]
# return dp[-1][-1]
複雜度分析
- 時間複雜度: O ( m n ) O(mn) O(mn)。
- 空間複雜度: O ( m n ) O(mn) O(mn)。
歡迎關注
公眾號 【書所集錄】
如有錯誤,煩請指出,歡迎指點交流。