62. 不同路径(中等)

Blind 75 › 62. 不同路径(中等) (第 11 章)
文章工具

题目

一个机器人站在 m 行、n 列的网格左上角,每次只能向右或向下走一格,问走到右下角总共有多少条不同路线。

换句话说:每一步只有「向右 / 向下」两个选择;把从左上角一路走到右下角的每步选择串起来就是一条路径,数一数这样的路径有多少条。

自造示例:m = 2、n = 3,答案是 3,三条路径分别是「右 → 右 → 下」「右 → 下 → 右」「下 → 右 → 右」。

再比如 m = 3、n = 3,答案是 6:第一行、第一列的格子都只有 1 条路径,内部格子等于「上方格子的路径数 + 左边格子的路径数」。

约束:m、n 都在 1 ~ 100;数据保证答案不超过 2×109(用 32 位整数即可)。

思路

一句话:走到某格只能来自上方或左方,所以该格的路径数 = 上方格子的路径数 + 左边格子的路径数。

先想最直白的:从左上角出发做 DFS,每一步分「向右、向下」两叉,走到右下角就记一条。这样能算对,但路径总数是组合数级别——对 m = n = 100,路径数是天文数字,枚举完全不可行。

关键观察:到格子 (i, j) 的路径,可以按最后一步分成互不重叠的两类:

  • 最后一步从上方 (i−1, j) 走下来;
  • 最后一步从左边 (i, j−1) 走过来。

这两类合起来覆盖了所有到 (i, j) 的路径,所以直接把两个数相加即可:dp[i][j] = dp[i−1][j] + dp[i][j−1]。

边界也好定:第一行的格子只能一直向右,第一列的格子只能一直向下,因此它们的路径数都是 1。

于是选定做法:自底向上的网格 DP。先把第一行、第一列填成 1,再按从上到下、从左到右的顺序填内部格子;每个格子只依赖上方和左方,填的时候这两个值都已经算好了。

解法

用一张 m×n 的表 dp,dp[i][j] 表示从左上角走到 (i, j) 的路径数:

  1. 初始化:第一行、第一列全部为 1。
  2. 从 i = 1、j = 1 开始,逐个计算 dp[i][j] = dp[i−1][j] + dp[i][j−1]。
  3. 返回右下角 dp[m−1][n−1]。

以 m = 3、n = 3 为例,填表过程如下:

dp 表(3×3)第 0 列第 1 列第 2 列
第 0 行111
第 1 行123
第 2 行136

右下角的值 6 就是答案。下面 C++ 给出二维版,Python 给出滚动数组版——两者是同一个转移,只是空间占用不同。

下图把上面 3 个步骤串成流程,并逐步演示:

62. 不同路径(中等) 解法步骤流程图
图① 解法步骤流程图(共 3 步)。
62. 不同路径(中等) 按步骤逐步执行的动画
动图② 按步骤依次推进(循环播放)。

C++

C++ 片段需补全 main() 函数才能运行在实训台打开 →
class Solution {
public:
 int uniquePaths(int m, int n) {
 vector<vector<int>> dp(m, vector<int>(n, 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];
 }
 }

🔒

本篇为付费内容

您已阅读试读部分,购买后即可解锁全文。

⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。