LeetCode题解——64. 最小路径和

题目相关

题目链接

LeetCode中国,https://leetcode-cn.com/problems/minimum-path-sum/。

题目描述

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

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

示例

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

题目分析

LeetCode 给出本题难度中等。一个非常经典的动态规划问题。

本题的核心是:每次只能向下或者向右移动一步。我们可以使用动态规划自顶向下生成的方法来分析问题。

样例数据分析

根据题目的意思,我们从数组的左上角出发,也就是(0, 0)这个位置出发。根据规则,我们只能向下或者向右移动一次,一次走一步。如下图所示。

LeetCode题解——64. 最小路径和_第1张图片

根据这个前提条件,我们需要构造一个动态规划数组,也就是 DP 数组,用来描述走到 i, j 这个位置的最小代价。

初始状态

原始数据的初始状态如下图所示。

LeetCode题解——64. 最小路径和_第2张图片

DP 数组的初始状态可以这样推导出。

1、dp[0][0] 这个点。自然最小代价就是数组的(0,0)点的值,也就是 dp[0][0]=grid[0][0]=1。

2、第 0 行。根据行走规则,只能向右移动。也就意味着 dp[0][j] = dp[0][j-1]+grid[0][j-1],因为我们是从右边移动过来,所以代价就是右边 dp 数据加上 grid 本格的数据。

3、第 0 列。根据行走规则,只能向下移动。也就意味着 dp[i][0] = dp[i-1][0]+grid[i-1][0],因为我们是从上边移动过来,所以代价就是上边 dp 数据加上 grid 本格的数据。

这样,我们就得到了 DP 数组对应的初始状态。

LeetCode题解——64. 最小路径和_第3张图片

DP 数组构造

这样,假设一个位置为(i,j),根据移动规则,要走到这个位置,只有两个可能:1、从(i-1, j)向下走一步;2、从(i, j-1)向右走一步。因此我们可以推导出 dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + gird[i][j]。

1、(1, 1)点。从(0, 1)点走过来的代价是 4+5=9;从(1, 0)点走过来的代价是 2+5=7。因此最小代价为 7。

2、(1, 2)点。从(0, 2)点走过来的代价是 5+1=6;从(1, 1)点走过来的代价是 7+1=8。因此最小代价为 6。

3、(2, 1)点。从(1, 1)点走过来的代价是 7+2=9;从(2, 0)点走过来的代价是 6+2=8。因此最小代价为 8。

4、(2, 2)点。从(1, 2)点走过来的代价是 6+1=7;从(2, 1)点走过来的代价是 8+1=9。因此最小代价为 7。

这样,利用一个两重循环,我们可以推导出完整的 DP 数组。对应数据如下:

LeetCode题解——64. 最小路径和_第4张图片

这样,我们就得到最终的最小代价为 dp[2][2]=7。

AC 参考代码

class Solution {
public:
    int minPathSum(vector>& grid) {
        //获取行
        int row = grid.size();
        int col = grid[0].size();

        //特殊处理
        if (0==row || 0==col) {
            return 0;
        }

        //DP数组
        auto dp = vector>(row, vector(col));
        //初始化DP
        dp[0][0] = grid[0][0];
        //第0行数据
        int i,j;
        for (j=1; j

LeetCode题解——64. 最小路径和_第5张图片

算法分析

时间复杂度

O(n^{2})

空间复杂度

O(n^{2})

你可能感兴趣的:(OJ题解,#,LeetCode题解,#,动态规划)