力扣小白刷题之64题最小路径和

题目描述

给定一个包含非负整数的 m * n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
每次只能向下或向右移动一步。

思路

参考自:https://leetcode-cn.com/problems/minimum-path-sum/solution/zui-xiao-lu-jing-he-dong-tai-gui-hua-gui-fan-liu-c/

动态规划
在这里插入图片描述

  • 状态定义:
    • 设 dp 为 m * n 矩阵,其中 dp[i][j] 的值代表直到走到 (i, j) 的最小路径和。
  • 转移方程:
    i 是行(m = grid.length),j是列(n = grid[0].length)
    当前单元格(i, j)只能从左方单元格(i, j - 1) 与上方单元格(i - 1, j)走到因此只需要考虑矩阵左边界和右边界
    • 走到当前单元格(i, j)的最小路径和 = “从左方单元格(i, j - 1) 与上方单元格(i - 1, j)走来的 两个最小路径和中较小的” + 当前单元格值 grid[i][j]。具体分为以下 4 种情况:
      1. 当左边和上边都不是矩阵边界时: 即 i != 0,j != 0 时,dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
      2. 当只有左边是矩阵边界时: 只能从上面来,即当 i != 0,j = 0时,dp[i][j] = dp[i - 1][j] + grid[i][j];
      3. 当只有上边是矩阵边界时: 只能从左边来,即当 i = 0, j! = 0时,dp[i][j] = dp[i][j - 1] + grid[i][j];
      4. 当左边和上边都是矩阵边界时: 即当 i = 0, j = 0时,其实就是起点,dp[i][j] = grid[i][j];
  • 初始状态:
    • dp 初始化即可,不需要修改初始 0 值。
  • 返回值:
    • 返回 dp矩阵右下角值,即走到终点的最小路径和。

其实我们完全不需要建立 dp 矩阵浪费额外空间,直接遍历 grid[i][j] 修改即可。这是因为:grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j];原grid矩阵元素中被覆盖为dp元素后(都处于当前遍历点的左上方),不会再被使用到。
这种方法是:不使用额外空间的动态规划
时间复杂度: O(mn),遍历整个grid矩阵元素。
空间复杂度: O(1),直接修改矩阵,不使用额外空间。

代码在这里插入图片描述

还可以采用:二维动态规划,即使用dp二维矩阵,空间和时间复杂度都为O(mn)。

还可以使用一维动态规划
转移方程:dp[j] = min(dp[j], dp[j - 1]) + grid(i, j),左边和上边都不生矩阵边界时适用,返回值为 dp[n - 1]
时间复杂度:O(mn)
空间复杂度:O(n),额外的一维数组,和一行大小相同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值