最小路径和:二维动态规划基础解法
423 字
2 分钟
最小路径和:二维动态规划基础解法
核心结论
如果每一步只能向右或向下,到达单元格 (i, j) 的最后一步只能来自上方或左侧。用 dp[i][j] 表示到达该位置的最小路径和,就能从左上角逐格计算到右下角。
问题
给定非负整数网格,从左上角移动到右下角,每次只能向右或向下,求路径上数字之和的最小值。
输入:
1 3 1
1 5 1
4 2 1
输出:7
状态设计
状态转移方程为:
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
第一行只能从左侧到达,第一列只能从上方到达,因此需要单独初始化。这一步可以避免在主循环里反复判断边界。
Java 实现
class Solution {
public int minPathSum(int[][] grid) {
int rows = grid.length;
int columns = grid[0].length;
int[][] dp = new int[rows][columns];
dp[0][0] = grid[0][0];
for (int i = 1; i < rows; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
for (int j = 1; j < columns; j++) {
dp[0][j] = dp[0][j - 1] + grid[0][j];
}
for (int i = 1; i < rows; i++) {
for (int j = 1; j < columns; j++) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1])
+ grid[i][j];
}
}
return dp[rows - 1][columns - 1];
}
}
正确性与复杂度
每个状态只依赖已经计算过的上方和左侧状态。两者覆盖了所有合法的最后一步,取较小值后加上当前格子代价,即得到当前位置的最优解。
- 时间复杂度:
O(mn)。 - 空间复杂度:
O(mn);进一步可以压缩为一维数组O(n)。
验证
验证单行、单列、1 x 1 网格和常规二维网格。对于示例网格,返回值应为 7。
参考
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
最小路径和:压缩二维动态规划
algorithms从只能向右或向下移动的约束推导最小路径和状态转移,并将二维状态表压缩为一维数组。
2
爬楼梯:从递推关系到动态规划
algorithms从最后一步的两种选择推导斐波那契式状态转移,并用常量空间实现爬楼梯方案计数。
3
最大正方形:用相邻状态确定边长
algorithms定义以当前单元格为右下角的最大正方形边长,推导三邻居状态转移,并给出 Java 动态规划实现。
4
缺失数字:标记数组解法
algorithms使用长度为 n+1 的标记数组记录出现过的数字,并讨论异或与数学求和等低空间替代方案。
5
二叉树中序遍历:递归与显式栈
algorithms从左、根、右的访问顺序出发,实现二叉树中序遍历,并比较递归与显式栈两种写法的边界和复杂度。
随机文章随机推荐


