《每日一题》62. Unique Paths 不同路径
一個機器人位于一個 m x n?網(wǎng)格的左上角 (起始點在下圖中標記為 “Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網(wǎng)格的右下角(在下圖中標記為 “Finish” )。
問總共有多少條不同的路徑?
?
示例 1:
輸入: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
- 題目數(shù)據(jù)保證答案小于等于 2 * 109
DFS
今天這題那么簡單???直接深搜就能出結(jié)果???不可能吧。
Python
class Solution:def uniquePaths(self, m: int, n: int) -> int:def dfs(x: int, y: int):# print(f"x = {x}, y = {y}")if x == m - 1 and y == n - 1:return 1if x > m - 1 or y > n - 1:return 0return dfs(x + 1, y) + dfs(x, y + 1)return dfs(0, 0)果然超時了,沒過,DFS不行那就得DP了。
DP
我們用 f(i,j)f(i, j)f(i,j) 表示從左上角走到 (i,j)(i, j)(i,j) 的路徑數(shù)量,其中 iii 和 jjj 的范圍分別是 [0,m)[0, m)[0,m) 和 [0,n)[0, n)[0,n)。
由于我們每一步只能從向下或者向右移動一步,因此要想走到 (i,j)(i, j)(i,j),如果向下走一步,那么會從 (i?1,j)(i-1, j)(i?1,j) 走過來;如果向右走一步,那么會從 (i,j?1)(i, j-1)(i,j?1) 走過來。因此我們可以寫出動態(tài)規(guī)劃轉(zhuǎn)移方程:
f(i,j)=f(i?1,j)+f(i,j?1)f(i, j) = f(i-1, j) + f(i, j-1) f(i,j)=f(i?1,j)+f(i,j?1)
需要注意的是,如果 i=0i=0i=0,那么 f(i?1,j)f(i-1,j)f(i?1,j) 并不是一個滿足要求的狀態(tài),我們需要忽略這一項;同理,如果 j=0j=0j=0,那么 f(i,j?1)f(i,j-1)f(i,j?1) 并不是一個滿足要求的狀態(tài),我們需要忽略這一項。
初始條件為 f(0,0)=1f(0,0)=1f(0,0)=1,即從左上角走到左上角有一種方法。
最終的答案即為 f(m?1,n?1)f(m-1,n-1)f(m?1,n?1)。
Python
class Solution:def uniquePaths(self, m: int, n: int) -> int:dp = [[1] * n] + [[1] + [0] * (n - 1) for _ in range(m - 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]復(fù)雜度分析
-
時間復(fù)雜度:O(mn)O(mn)O(mn)。
-
空間復(fù)雜度:O(mn)O(mn)O(mn),即為存儲所有狀態(tài)需要的空間。注意到 f(i,j)f(i, j)f(i,j) 僅與第 iii 行和第 i?1i-1i?1 行的狀態(tài)有關(guān),因此我們可以使用滾動數(shù)組代替代碼中的二維數(shù)組,使空間復(fù)雜度降低為 O(n)O(n)O(n)。此外,由于我們交換行列的值并不會對答案產(chǎn)生影響,因此我們總可以通過交換 mmm 和 nnn 使得 m≤nm \leq nm≤n,這樣空間復(fù)雜度降低至 O(min?(m,n))O(\min(m, n))O(min(m,n))。
滾動數(shù)組實現(xiàn)
class Solution:def uniquePaths(self, m: int, n: int) -> int:dp = [[1] * n] + [[1] + [0] * (n - 1)]for i in range(1, m):for j in range(1, n):dp[i % 2][j] = dp[abs(i % 2 - 1)][j] + dp[i % 2][j - 1]return dp[abs(m % 2 - 1)][n - 1]組合數(shù)學(xué)
從左上角到右下角的過程中,我們需要移動 m+n?2m+n-2m+n?2 次,其中有 m?1m-1m?1 次向下移動,n?1n-1n?1 次向右移動。因此路徑的總數(shù),就等于從 m+n?2m+n-2m+n?2 次移動中選擇 m?1m-1m?1 次向下移動的方案數(shù),即組合數(shù):
Cm+n?2m?1=(m+n?2m?1)=(m+n?2)!(m?1)!(n?1)!C_{m+n-2}^{m-1}=\begin{pmatrix} m+n-2\\m-1\end{pmatrix}=\frac{(m+n-2)!}{(m-1)!(n-1)!}Cm+n?2m?1?=(m+n?2m?1?)=(m?1)!(n?1)!(m+n?2)!?
Python
class Solution:def uniquePaths(self, m: int, n: int) -> int:return comb(m + n - 2, n - 1)復(fù)雜度分析
-
時間復(fù)雜度:O(m)O(m)O(m)。由于我們交換行列的值并不會對答案產(chǎn)生影響,因此我們總可以通過交換 mmm 和 nnn 使得 m≤nm \leq nm≤n,這樣空間復(fù)雜度降低至 O(min?(m,n))O(\min(m, n))O(min(m,n))。
-
空間復(fù)雜度:O(1)O(1)O(1)。
總結(jié)
以上是生活随笔為你收集整理的《每日一题》62. Unique Paths 不同路径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《每日一题》842. Split Arr
- 下一篇: tqdm: ‘module‘ objec