最小路径和

最小路径和

64. 最小路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:

[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]

输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。

动态规划

设f(m,n)为左上角到点(m,n)的最小路径和
则状态转移方程

dp(m,n)=grid(m,n) + min{dp(m,n-1),dp(m-1,n)}, 当m>0,n>0

base case:m=0或n=0时,即二维dp表格的首行,首列

dp(0,0)=grid(0,0);
dp(0,n)=dp(0,n-1)+grid(0,n);n>=1dp(m,0)=dp(m-1,0)+grid(m,0);m>=1
class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        if(grid.empty()) return 0;
           
        //base case
        int row=grid.size();
        int col=grid[0].size();
        vector<vector<int>> dp(row,vector<int>(col,0));
        //首行
        dp[0][0]=grid[0][0];
        for(int i=0;i<col-1;i++)
            dp[0][i+1]=dp[0][i]+grid[0][i+1];
        //首列
        for(int j=0;j<row-1;j++)
            dp[j+1][0]=dp[j][0]+grid[j+1][0];

        for(int m=1;m<row;m++){
            for(int n=1;n<col;n++){
                dp[m][n]=min(dp[m][n-1],dp[m-1][n])+grid[m][n];
            }
        }

        return dp[row-1][col-1];       
    }
};

带备忘录的递归

class Solution{
    int helper(vector<vector<int>>& grid,vector<vector<int>>& memory,int row,int col){
        if(row<0||col<0)    return INT_MAX;//用于首行,首列的边界情况
        if(memory[row][col]!=-1)    return memory[row][col];
        memory[row][col]=min(helper(grid,memory,row,col-1),helper(grid,memory,row-1,col))+grid[row][col];
        return memory[row][col];
    }
public:
    int minPathSum(vector<vector<int>>& grid){
        int row=grid.size();
        int col=grid[0].size();
        //备忘录
        vector<vector<int>> memory(row,vector<int>(col,-1));
        memory[0][0]=grid[0][0];
        return helper(grid,memory,row-1,col-1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值