62. 不同路径

110 阅读2分钟

题目描述

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

1697422740-adxmsI-image.png

示例

示例 1:

输入: m = 3, n = 7
输出: 28
从左上角开始,总共有 28 条路径可以到达右下角。
1. 向右 -> 向右 -> 向右 -> 向右...-> 向下 -> 向下
2. 向右 -> 向下 -> 向右 -> 向右...-> 向下
3. ...

条件约束

  • 1 <= m, n <= 100
  • 题目数据保证答案小于等于 2 * 109

题目描述重点划词

  • 左上角
  • 右下角
  • 总共有多少条不同的路径

思考

从题目描述的关键词中不难看出,这好像是一个排列组合的问题,因为我们从示例可以看的出来,count("turn right"), count("turn down") 的值是一定的都等于 m-1 和 n-1,如果排列组合学的好的同学应该直接通过公式就能算出来,但是数学公式我早就不记得了而且我也不会推导,作为开发人员如果是工作好几年的我怎么可能做出来呢?这不是扯淡嘛,但是这个题目不止只有排列组合的做法,动态规划也可以!从 Finsh 点向前推我们可以看的出来图中点能到达 Finsh 点的只有两个那就是它上方的点和它左边的点,因为只能向下和向右,依次倒推我们就能得出来动态规划的转移方程:

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

其中有个问题边界怎么搞,因为 [0][j] 没有上方的的点 [i][0] 没有左边的点,思考中...嗯好像很简单,到达它们这些点的路径路数只有一条最上方的点只能从左边过来,最左边的点只能从上方过来,所以 dp[0][j]、dp[i][0] 永远等于 1

下面是AreaZer同学给出的示例代码

func uniquePaths(m int, n int) int {
   dp := make([][]int, m)
   for i := range dp {
      dp[i] = make([]int, n)
      dp[i][0] = 1 // 最左边
   }
   for i := 0; i < n; i++ {
      dp[0][i] = 1 // 最上边
   }
   for i := 1; i < m; i++ {
      for j := 1; j < n; j++ {
         dp[i][j] = dp[i-1][j] + dp[i][j-1]
      }
   }
   return dp[m-1][n-1] // Finsh
}

image.png

题目来源 62. 不同路径