LeetCode 64. 最小路径和c++/java详细题解
Posted 林深时不见鹿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 64. 最小路径和c++/java详细题解相关的知识,希望对你有一定的参考价值。
1、题目
给定一个包含非负整数的 m x n
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明: 每次只能向下或者向右移动一步。
示例 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] <= 100
2、思路
(动态规划) O ( m ∗ n ) O(m*n) O(m∗n)
状态表示: f[i,j]
表示从(0,0)
走到(i,j)
的最小路径和。那么,f[n-1][m-1]
就表示从网格左上角到网格右下角的最小路径和,即为答案。
状态转移:
由于限制了只会向下走或者向右走,因此到达(i,j)
有两条路径
- 从上方转移过来,
f[i][j] = f[i-1][j] + grid[i][j]
- 从左方转移过来,
f[i][j] = f[i][j-1] + grid[i][j]
因此,状态计算方程为: f[i][j] = max(f[i - 1][j], f[i][j - 1]) + grid[i][j]
, 从向右和向下两条路径中选择路径之和最小的转移过来,再加上grid[i][j]
的值。
初始化条件: f[0][0] = grid[0][0]
, 其余都初始化为正无穷。
分析图示:
时间复杂度分析: O ( m ∗ n ) O(m*n) O(m∗n),其中 m m m和 n n n分别是网格的行数和列数 。
3、c++代码
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int n = grid.size();
int m = grid[0].size();
vector<vector<int>> f(n, vector<int>(m, INT_MAX));
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ ) {
if (!i && !j) f[i][j] = grid[i][j]; //初始化 f[0][0] = grid[0][0]
else
{
if (i) f[i][j] = min(f[i][j], f[i - 1][j] + grid[i][j]);//如果可以从上方转移过来
if (j) f[i][j] = min(f[i][j], f[i][j - 1] + grid[i][j]);//如果可以从左方转移过来
}
}
return f[n - 1][m - 1];
}
};
4、java代码
class Solution {
public int minPathSum(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
int[][] f = new int[n][m];
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ ) {
if (i == 0 && j == 0) f[i][j] = grid[i][j]; //初始化 f[0][0] = grid[0][0]
else
{
f[i][j] = 0x3f3f3f3f;
if (i > 0) f[i][j] = Math.min(f[i][j],f[i - 1][j] + grid[i][j]);//如果可以从上方转移过来
if (j > 0) f[i][j] = Math.min(f[i][j],f[i][j - 1] + grid[i][j]);//如果可以从左方转移过来
}
}
return f[n - 1][m - 1];
}
}
原题链接: 64. 最小路径和
以上是关于LeetCode 64. 最小路径和c++/java详细题解的主要内容,如果未能解决你的问题,请参考以下文章