首页 > 代码库 > [C++]LeetCode: 51 Minimum Path Sum

[C++]LeetCode: 51 Minimum Path Sum

题目:

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

思路:

典型的动态规划问题。

设dp[i][j]表示从左上角到grid[i][j]的最小路径和。那么dp[i][j] = grid[i][j] + min( dp[i-1][j], dp[i][j-1] );

下面的代码中,为了处理计算第一行和第一列的边界条件,我们令dp[i][j]表示从左上角到grid[i-1][j-1]的最小路径和,最后dp[m][n]是我们所求的结果。

复杂度:O(mn)

Attention:

1. 初始化vector容器时,需要将初值设为INT_MAX,因为后面要比较较小值。

  vector<vector<int>>dp(row+1, vector<int>(col+1, INT_MAX));

2. 需要初始化dp[0][1]的值,动态规划需要设定初值。

3. 注意规划的迭代公式,dp存储了一个可走路径的表。

    dp[m][n] is a matrix store the min value of every location we can get.

边界处理dp[i][j]表示从左上角到grid[i-1][j-1]的最小路径和。

dp[ri][ci] = grid[ri-1][ci-1] + min(dp[ri-1][ci], dp[ri][ci-1]);

AC Code:

class Solution {
public:
    int minPathSum(vector<vector<int> > &grid) {
        if(grid.empty() || grid[0].empty()) return 0;
        int row = grid.size();
        int col = grid[0].size();
        
        //初始化为INT_MAX,因为后面要取最小值
        vector<vector<int>>dp(row+1, vector<int>(col+1, INT_MAX));
        
        //dp[0][1]需初始化才能开始
        dp[0][1] = 0;
        for(int ri = 1; ri <= row; ri++)
        {
            for(int ci = 1; ci <= col; ci++)
            {
                dp[ri][ci] = grid[ri-1][ci-1] + min(dp[ri-1][ci], dp[ri][ci-1]);
            }
        }
        
        return dp[row][col];
    }
};

优化算法:空间复杂度降低到O(min(row, col))

思路:dp[i][j] 只和上一行的dp[i-1][j]和上一列的dp[i][j-1]有关,dp[i][j]是一行一行计算的(根据循环),dp[j-1]表示前一列的值(已经更新为本行的前一列的值),dp[j]保存了上一行的值(dp的值逐行更新,始终存储着一行的值,使用时即对应上一行的值(还没有更新))。基于这个原理,我们不需要存储所有的列的值。可以将空间复杂度降到O(min(row, col))

Attention:

1. 最后取值时,取vector容器的最后的数 。dp.back();

2. 初始化dp[1] = 0; 循环开始dp[1] = grid[0][0] + min(dp[1], dp[0]); <=> dp[1] = grid[0][0] + min(0, INT_MAX);

技术分享

AC Code:

class Solution {
public:
    int minPathSum(vector<vector<int> > &grid) {
        if(grid.empty() || grid[0].empty()) return 0;
        int row = grid.size();
        int col = grid[0].size();
        
        vector<int> dp(col+1, INT_MAX);
        
        dp[1] = 0;
        for(int ri = 1; ri <= row; ri++)
        {
            for(int ci = 1; ci <= col; ci++)
            {
                dp[ci] = grid[ri-1][ci-1] + min(dp[ci], dp[ci-1]);   
            }
        }
        
        return dp.back();
    }
};



[C++]LeetCode: 51 Minimum Path Sum