首页 > 代码库 > [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