LeetCode#64 最小路径和 Java

@author: sdubrz
@date: 2020.04.17
题号: 64
题目难度: 中等
考察内容: 动态规划
原题链接 https://leetcode-cn.com/problems/minimum-path-sum/
题目的著作权归领扣网络所有,商业转载请联系官方授权,非商业转载请注明出处。
解题代码转载请联系 lwyz521604#163.com

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

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

示例:

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

通过次数77,450 提交次数118,548

动态规划解法

使用动态规划的关键是寻找最优子结构。从起始位置出发,到第 m 行的元素必须经过第 m-1 行。因而要计算从初始位置到第 m 行中的元素的最小代价可以先计算到第 m-1 行中的元素的最小代价。

这样,这个问题的子结构就可以基本确定下来了。我们需要计算在已知前 i 行元素的情况下,从初始位置到第 i 行中的元素的代价。对于第 i 行中的第 j 个元素,到达它有两种途径:

  • 从第 i 行、第 j-1 个元素到达
  • 从第 i-1 行、第 j 个元素到达

我们需要挑选这两种途径中代价较小的那个。

我们每次读取矩阵的一行,计算从初始位置到当前行中元素的最小代价。由于在计算到第 i 行中元素的最小代价时,只需要查看到第 i-1 行元素的代价以及第 i 行中的元素本身,因而,在迭代的过程中,我们不需要再去更新前面的 i-2 行元素的代价。

下面是具体的代码实现:

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        if(m==0){
            return 0;
        }
        int n = grid[0].length;
        if(n==0){
            return 0;
        }

        for(int i=1; i<n; i++){
            grid[0][i] = grid[0][i] + grid[0][i-1];
        }

        for(int i=1; i<m; i++){
            grid[i][0] = grid[i-1][0] + grid[i][0];
            for(int j=1; j<n; j++){
                int s1 = grid[i][j] + grid[i][j-1];
                int s2 = grid[i][j] + grid[i-1][j];
                grid[i][j] = Math.min(s1, s2);
            }
        }

        return grid[m-1][n-1];
    }
}

在 LeetCode 系统中提交的结果如下所示

执行结果: 通过 显示详情
执行用时 : 3 ms, 在所有 Java 提交中击败了 89.15% 的用户
内存消耗 : 42.6 MB, 在所有 Java 提交中击败了 24.24% 的用户

图论方法

这个问题应该也可以通过构造一个有向图,然后用 Dijkstra 算法来求解。不过那种方法应该不会比动态规划的方法简单快捷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章