🙉饭不食,水不饮,题必须刷🙉
C语言免费动漫教程,和我一起打卡! 🌞《光天化日学C语言》🌞
LeetCode 太难?先看简单题! 🧡《C语言入门100例》🧡
数据结构难?不存在的! 🌳《数据结构入门》🌳
LeetCode 太简单?算法学起来! 🌌《夜深人静写算法》🌌
一、题目
1、题目描述
一个机器人位于一个 m × n m \times n m×n 网格的左上角。机器人每次只能 向下 或者 向右 移动一步。机器人试图达到网格的右下角。问总共有多少条不同的路径?
样例输入: m = 3 , n = 2 m = 3, n = 2 m=3,n=2
样例输出: 3 3 3
2、基础框架
- c++ 版本给出的基础框架代码如下:
class Solution {
public:
int uniquePaths(int m, int n) {
}
};
3、原题链接
二、解题报告
1、思路分析
- 你在 ( 1 , 1 ) (1,1) (1,1) 的位置,通过向右,或者向下,要走到 ( m , n ) (m,n) (m,n) 位置的方案数。
- 当 m = 1 m = 1 m=1 时,表示只能往右走,所以 ( 1 , i ) (1, i) (1,i) ( i ∈ [ 1 , n ] ) (i \in [1, n]) (i∈[1,n]) 的方案数就是 1。
- 当 n = 1 n = 1 n=1 时,表示只能往下走,所以 ( i , 1 ) (i, 1) (i,1) ( i ∈ [ 1 , m ] ) (i \in [1, m]) (i∈[1,m]) 的方案数就是 1。
- 抛开这两种情况不管, ( i , j ) (i, j) (i,j) 这个位置,一定是从 ( i − 1 , j ) (i-1, j) (i−1,j) 或者 ( i , j − 1 ) (i, j-1) (i,j−1) 过来的,于是,我们令 f ( i , j ) f(i, j) f(i,j) 代表从 ( 1 , 1 ) (1, 1) (1,1) 到 ( i , j ) (i, j) (i,j) 的方案数,则有:
- f ( i , j ) = f ( i − 1 , j ) + f ( i , j − 1 ) f(i, j) = f(i-1, j) + f(i, j-1) f(i,j)=f(i−1,j)+f(i,j−1)
- 于是 f ( m , n ) f(m, n) f(m,n) 就可以通过两层循环,递推计算出来了。
2、时间复杂度
- 状态数: O ( n m ) O(nm) O(nm)
- 状态转移: O ( 1 ) O(1) O(1)
- 时间复杂度: O ( n m ) O(nm) O(nm)
3、代码详解
class Solution {
int f[110][110]; // (1)
public:
int uniquePaths(int m, int n) {
for(int i = 1; i <= n; i++) {
f[1][i] = 1; // (2)
}
for(int i = 1; i <= m; ++i) {
f[i][1] = 1; // (3)
}
for(int i = 2; i <= m; ++i) {
for(int j = 2; j <= n; ++j) {
f[i][j] = f[i-1][j] + f[i][j-1]; // (4)
}
}
return f[m][n];
}
};
- ( 1 ) (1) (1) f [ i ] [ j ] f[i][j] f[i][j] 代表从 ( 1 , 1 ) (1,1) (1,1) 到 ( i , j ) (i,j) (i,j) 的方案数;
- ( 2 ) (2) (2) 初始化列数为 1 的情况;
- ( 3 ) (3) (3) 初始化行数为 1 的情况;
- ( 4 ) (4) (4) 利用二维递推进行求解;
三、本题小知识
动态规划最重要的就是想清楚状态转移方程,然后再考虑边界情况,计算出最终结果。