首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

LeetCode Minimum Path Sum - 網格最小路徑和 (DP 遞歸 + 備忘錄)

     編輯:C++ 入門

題目大意

給定 m × n 非負整數網格,從左上角 (0,0) 走到右下角 (m-1,n-1),每步只能向右或向下。求路徑上數字和的最小值。

遞歸 + 備忘錄 (Top-down DP)


class Solution {
    vector> memo;
    vector>& grid;
public:
    int minPathSum(vector>& grid) {
        this->grid = grid;
        int m = grid.size(), n = grid[0].size();
        memo.assign(m+1, vector(n+1, 0));
        return dfs(m, n);
    }
private:
    int dfs(int m, int n) { // 走到 (m-1, n-1) 的最小和
        if (m < 1 || n < 1) return INT_MAX/2; // 越界返回極大值
        if (m == 1 && n == 1) return grid[0][0];
        if (memo[m][n]) return memo[m][n];
        return memo[m][n] = min(dfs(m-1, n), dfs(m, n-1)) + grid[m-1][n-1];
    }
};

迭代 DP (Bottom-up,更推薦)


int minPathSum(vector>& grid) {
    int m = grid.size(), n = grid[0].size();
    vector> dp(m, vector(n));
    dp[0][0] = grid[0][0];
    for (int i = 1; i < m; ++i) dp[i][0] = dp[i-1][0] + grid[i][0];
    for (int j = 1; j < n; ++j) dp[0][j] = dp[0][j-1] + grid[0][j];
    for (int i = 1; i < m; ++i)
        for (int j = 1; j < n; ++j)
            dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
    return dp[m-1][n-1];
}

空間優化:單行滾動陣列


int minPathSum(vector>& grid) {
    int m = grid.size(), n = grid[0].size();
    vector dp(n);
    dp[0] = grid[0][0];
    for (int j = 1; j < n; ++j) dp[j] = dp[j-1] + grid[0][j];
    for (int i = 1; i < m; ++i) {
        dp[0] += grid[i][0];
        for (int j = 1; j < n; ++j)
            dp[j] = min(dp[j], dp[j-1]) + grid[i][j];
    }
    return dp[n-1];
}

複雜度

  • 時間:O(mn)
  • 空間:O(mn) (二維) 或 O(n) (滾動陣列)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved