64. 最小路径和
1.动态规划
-
本题与62. 不同路径、63. 不同路径 II的思路十分类似,依然可以方便的用动态规划的思想解决。究其本质,是因为更靠后的状态,其最优方案,取决于更靠前的两个状态,而与未来的状态无关,抓住这个性质,我们就能很快的理清楚状态转移方程。
-
与前两题类似,维护一个数组 d p [ m ] [ n ] dp[m][n] dp[m][n],代表到达位置i,j的最小路径和。本题当前状态并非上方、左方数值之和,而是左方、上方更小的一个加上当前位置的数字,状态转移方程为:
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + g r i d [ i ] [ j ] dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j] dp[i][j]=min(dp[i−1][j],dp[i][j−1])+grid[i][j]
class Solution { public: int minPathSum(vector<vector<int>>& grid) { int m=grid.size(),n=grid[0].size(); vector<vector<int>> dp(m,vector<int>(n)); dp[0][0]=grid[0][0]; for(int i=1;i<n;i++){ dp[0][i]=dp[0][i-1]+grid[0][i]; } for(int i=1;i<m;i++){ dp[i][0]=dp[i-1][0]+grid[i][0]; } 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]; } };
2.滚动数组优化
-
和前两题一样,可以使用滚动数组思想减小空间复杂度,不再赘述,做法和上面一样,只是减少了空间使用。
class Solution { public: int minPathSum(vector<vector<int>>& grid) { int m=grid.size(),n=grid[0].size(); vector<int> dp(n,0); dp[0]=grid[0][0]; for(int i=1;i<n;i++){ dp[i]=dp[i-1]+grid[0][i]; } for(int i=1;i<m;i++){ for(int j=0;j<n;j++){ if(j>=1){ dp[j]=min(dp[j],dp[j-1])+grid[i][j]; }else{ dp[j]=dp[j]+grid[i][j]; } } } return dp[n-1]; } };