Leetcode刷题详解——最小路径和

1. 题目链接:64. 最小路径和

2. 题目描述:

给定一个包含非负整数的 *m* x *n* 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

**说明:**每次只能向下或者向右移动一步。

示例 1:

Leetcode刷题详解——最小路径和_第1张图片

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 200

3. 解法(动态规划)

3.1 算法思路:

3.1.1 状态表示:

dp[i][j]表示:到达[i,j]位置处,最小路径和是多少

3.1.2 状态转移:

如果 dp[i][j]表示到达 [i,j]位置处的最小路径和,那么到达[i,j]位置之前的一小步,有两种情况:

  1. [i-1,j]向下走一步,转移到[i,j]位置
  2. [i,j-1]向右走一步,转移到[i,j]位置

dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1]

3.1.3 初始化:

可以在最前面加上一个辅助结点,帮助我们初始化。使用这种技巧要注意两个点:

  1. 辅助结点里面的值要保证后续填表是正确的

  2. 下标的映射关系

  3. 在本题中,添加一行和添加一列后,所有位置的值可以初始化为无穷大,然后让dp[0][1]=d[1][0]=0即可
    Leetcode刷题详解——最小路径和_第2张图片

3.1.4 填表顺序:

根据状态转移方程的推导来看,填表的顺序就是从上往下填每一行,每一行从左往右

3.1.5返回值:

根据状态表示,我们要返回的结果是dp[m][n]

3.2 C++算法代码:

class Solution {
public:
    int minPathSum(vector>& grid) {
        int m=grid.size();
        int n=grid[0].size();
        //创建dp表
        vector>dp(m+1,vector(n+1,INT_MAX));
        //初始化
        dp[0][1]=0,dp[1][0]=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-1][j-1];
            }
        }
        //返回结果
        return dp[m][n];
    }
};

你可能感兴趣的:(leetcode,算法,职场和发展)