Unique Paths

題目描述

一個 m × n 的網格,機器人在左上角 (0,0),目標在右下角 (m-1, n-1)。每次只能往下或往右走。回傳不同路徑的數量。

輸入:m = 3, n = 7
輸出:28

輸入:m = 3, n = 2
輸出:3

解題思路

1

定義狀態

dp[i][j] = 從 (0,0) 到 (i,j) 的不同路徑數

2

邊界條件

第一行 dp[0][j]=1(只能一路向右),第一列 dp[i][0]=1(只能一路向下)

3

轉移方程

dp[i][j] = dp[i-1][j] + dp[i][j-1]。到達 (i,j) 只能從上方 (i-1,j) 或左方 (i,j-1) 過來

4

空間優化

逐行計算時,dp[j] 更新前存著上一行的值(即 dp[i-1][j]),dp[j-1] 已更新為當前行的值(即 dp[i][j-1])

5

回傳結果

dp[n-1](一維優化後)或 dp[m-1][n-1] 即為答案

程式碼

C#

csharp
public class Solution {
    public int UniquePaths(int m, int n) {
        // 空間優化:用一維陣列
        int[] dp = new int[n];
        Array.Fill(dp, 1); // 第一行全是 1
        
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[j] += dp[j - 1]; // dp[j] 本身是上方的值,dp[j-1] 是左邊的值
            }
        }
        return dp[n - 1];
    }
}

TypeScript

typescript
function uniquePaths(m: number, n: number): number {
    const dp = new Array(n).fill(1);
    
    for (let i = 1; i < m; i++) {
        for (let j = 1; j < n; j++) {
            dp[j] += dp[j - 1];
        }
    }
    return dp[n - 1];
}

Python

python
def uniquePaths(m: int, n: int) -> int:
    dp = [1] * n  # 第一行都是 1
    
    for i in range(1, m):
        for j in range(1, n):
            dp[j] += dp[j - 1]  # 上方 + 左方
    
    return dp[n - 1]

複雜度分析

| | Time | Space | |--|------|-------| | 本解法 | O(m × n) | O(n) |

圖解

(0,0) = 1
(0,1) = 1
(0,2) = 1
(1,0) = 1
(1,1) = 2
(1,2) = 3
(2,0) = 1
(2,1) = 3
(2,2) = 6

3×3 的 DP 表格:邊界(第一行和第一列)都是 1,內部格子等於上方加左方。 例如 (1,1)=2 來自上方 (0,1)=1 加左方 (1,0)=1;最終 (2,2)=6 是答案。

進階觀點

💡面試追問

Q: 數學解法怎麼做? A: 從左上到右下共走 (m-1)+(n-1) = m+n-2 步,其中選 m-1 步向下(其餘向右),答案是組合數 C(m+n-2, m-1)。計算時要注意大數溢位,可以用逐步除法或取模處理。

Q: Unique Paths II(有障礙物)怎麼改? A: 在 DP 初始化和轉移時,遇到障礙格子直接設 dp=0(不可到達),其餘邏輯不變。如果起點或終點是障礙則直接回傳 0。第一行/列若中途有障礙,障礙之後的格子也都是 0。

Q: Minimum Path Sum(帶權版)的差異? A: 轉移從加法改成取 min:dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1]),框架完全相同,只是聚合函數從「求和」變成「取最小」。

Q: 空間優化的關鍵洞察是什麼? A: 逐行計算時 dp[j] 在被更新前是上一行的值(dp[i-1][j]),而 dp[j-1] 已被更新為當前行的值(dp[i][j-1]),所以 dp[j] += dp[j-1] 完美等價 2D 轉移,不需要兩個陣列。

邊界情況

理解測驗

🤔 為什麼第一行和第一列的路徑數都是 1?

🤔 空間優化中 dp[j] += dp[j-1] 為什麼等價於 dp[i][j] = dp[i-1][j] + dp[i][j-1]?

你可能也想看

790. Domino and Tromino Tiling1143. Longest Common Subsequence

按 ← → 鍵切換課程