题目
类型:动态规划
难度:中等
解题思路
方法一:动态规划
1、用 f(i,j)
表示从左上角走到 (i,j)
的路径数量,其中 i 和 j 的范围分别是 [0,m)
和 [0,n)
。
2、由于每一步只能从向下或者向右移动一步,因此要想走到 (i,j)
,如果向下走一步,那么会从(i−1,j)
走过来;如果向右走一步,那么会从 (i,j−1)
走过来。
因此得出动态规划转移方程:f(i, j) = f(i-1, j) + f(i, j-1)
3、需要注意的是,如果i=0,那么 f(i−1,j)
并不是一个满足要求的状态,需要忽略这一项;同理,如果j=0,需要忽略这一项。
4、初始条件为 f(0,0)=1
,即从左上角走到左上角有一种方法。最终的答案即为f(m−1,n−1)
细节:将所有的 f(0,j) 以及 f(i,0) 都设置为边界条件,它们的值均为 1。
方法二:组合数学
代码
方法一
class Solution {
public int uniquePaths(int m, int n) {
int[][] f = new int[m][n];
for (int i = 0; i < m; ++i) {
f[i][0] = 1;
}
for (int j = 0; j < n; ++j) {
f[0][j] = 1;
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
return f[m - 1][n - 1];
}
}
方法二
class Solution {
public int uniquePaths(int m, int n) {
long ans = 1;
for (int x = n, y = 1; y < m; ++x, ++y) {
ans = ans * x / y;
}
return (int) ans;
}
}