不同路径——动态规划基础题

62 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?

 思路

第一次做这道题时有些懵,还无法直接根据题意以及要求的结果想出递推公式,是通过在纸上写下 dp 数组的各个格子的值并观察里面的推导关系才得出来递推公式的,对于动态规划五部曲还不是很熟,今天第二次做,几分钟就解决,递推公式看一眼就得出,得益于一刷了一遍代码随想录的动态规划,感谢Carl哥!废话不多说,开始本题。

本题给出机器人起点为左上角,终点为右下角,如果刷过Carl哥的动态规划就可以很快得出:除了第一行和第一列(因为这俩是要初始化的),到达其余的任意一个格子的路径数来源于当前网格的 上面或左边 这用于推递推公式。明确了思路,下面就按照动态规划五部曲细解。

确定 dp 数组的含义

dp[i][j] 代表机器人到达第 i + 1 行第 j + 1 列(因为i、j从0索引开始)格子处共有 dp[i][j] 种不同路径数。

确定递推公式

由于机器人只能向下或向右移动,因此到达任意一个格子的路径数来源于当前网格的 上面或左边 (第一行和第一列除外,因为这俩需要初始化),故 dp[i][j] 取上面一个格子的不同路径数 dp[i - 1][j] 和左边紧接着的一个格子的不同路径数 dp[i][j - 1] 之和,因此得出递推公式:

dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

初始化 dp 数组

初始化 dp 数组看递推公式,递推公式中 dp[i][j] 来源于 dp[i - 1][j] 和 dp[i][j - 1] ,意味着需要初始化第一列和第一行。

初始化为多少呢?初始化不能靠感觉,需要推出来,初始化牢记 dp 数组的含义。首先看第一行每个格子的不同路径数 dp[0][j] 代表机器人到达第一行的某一个格子的 不同路径数 那么到达第一行的任意一个格子的路径数只有一种,一步到底,因此初始化为 1,第一行第一个格子呢?这是机器人的起点,到达该格子的不同路径数只有一种,即不走,故初始化为 1。

第一列的初始化和第一行是一样的,原因也和上面是一样一样的,一路走到底只有一种方法,初始化为 1。

for(int i = 0; i < n; i++) dp[0][i] = 1;
for(int i = 0; i < m; i++) dp[i][0] = 1;

确定遍历顺序

从递推公式 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 以及上面思路中的示意图看得出,求 dp[i][j] 需要已知 dp[i - 1][j] 和 dp[i][j - 1] ,这俩都来源于上方和左边,故遍历顺序是 从上到下、从左到右

for(int i = 1; i < m; i++) {
   for(int j = 1; j < n; j++) {
      dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
   }
}

举例推导dp数组

代码实现

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int i = 0; i < n; i++) dp[0][i] = 1;
        for(int i = 0; i < m; i++) dp[i][0] = 1;

        for(int i = 1; i < m; i++) {
            for(int j = 1; j < n; j++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }
}

 动态规划中如果无法快速在大脑中找到 递推公式,勤奋点,把dp数组在纸上模拟一遍,这方法在后面理解背包问题中给了我很大的帮助!

《代码随想录》刷题记

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值