[Leetcode解題] 62. Unique Paths
28 December 2024
medium
dp
題目
62. Unique Paths 一個機器人位於 $m \times n$ 的網格的左上角(即 $\text{grid}[0][0]$)。機器人嘗試移動到網格的右下角(即 $\text{grid}[m - 1][n - 1]$)。在任意時刻,機器人只能向下或向右移動。
給定兩個整數 $m$ 和 $n$,返回機器人從左上角移動到右下角的所有唯一路徑的數量。
約束條件:
測試數據保證答案小於等於 $2 \times 10^9$。
解題思路
這是一道典型的動態規劃(Dynamic Programming)問題,也可以用數學組合的方法解決。以下分別介紹兩種解法:
方法一:動態規劃 (Dynamic Programming)
- 定義一個 $dp$ 二維陣列,$dp[i][j]$ 表示從左上角移動到 $(i, j)$ 的唯一路徑數量。
- 初始化:
- $dp[0][0] = 1$(起始位置)。
- 第一列 $dp[i][0] = 1$,因為從 $(0, 0)$ 移到任意位置 $(i, 0)$ 都只能向下移動。
- 第一行 $dp[0][j] = 1$,因為從 $(0, 0)$ 移到任意位置 $(0, j)$ 都只能向右移動。
- 狀態轉移方程:
$dp[i][j] = dp[i-1][j] + dp[i][j-1]$
即到達 $(i, j)$ 的路徑數為從上方 $(i-1, j)$ 到達的路徑數加上從左側 $(i, j-1)$ 到達的路徑數。 - 最終結果為 $dp[m-1][n-1]$。
方法二:數學組合
機器人從左上角移動到右下角,需要總共移動 $m-1$ 步向下,和 $n-1$ 步向右,共 $m+n-2$ 步。從這些步數中選出 $m-1$ 步向下或 $n-1$ 步向右的組合數為答案: $\text{C}(m+n-2, m-1) = \frac{(m+n-2)!}{(m-1)!(n-1)!}$
這種方法利用排列組合公式,計算速度快且不需要額外空間。
Python 實作
動態規劃解法
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# 初始化 dp 陣列
dp = [[1] * n for _ in range(m)]
# 填充 dp 陣列
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]
數學組合解法
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
return math.comb(m + n - 2, m - 1)
時間與空間複雜度分析
動態規劃
- 時間複雜度:$O(m \times n)$,需要填滿 $m \times n$ 的 dp 表格。
- 空間複雜度:
- $O(m \times n)$,需要存儲 dp 表格。
- 如果優化為一維陣列(使用滾動陣列),空間複雜度可降為 $O(n)$。
數學組合
- 時間複雜度:$O(\min(m, n))$,$(m−1)$ 和 $(n−1)$ 中較小的那一項,決定了需要計算多少步。
- 組合數公式為:$C(m+n-2, m-1) = \frac{(m+n-2)!}{(m-1)! \cdot (n-1)!}$。計算這個公式時,實際上只需要計算部分階乘,而不需要完整地展開所有階乘。
- 如果 $m≤n$, 計算為: $C(m+n-2, m-1) = \frac{(m+n-2) \cdot (m+n-3) \cdot \dots \cdot n}{(m-1)!}$
- 如果 $n≤m$, 計算為: $C(m+n-2, n-1) = \frac{(m+n-2) \cdot (m+n-3) \cdot \dots \cdot m}{(n-1)!}$
- 空間複雜度:$O(1)$,僅用常數空間。