题目

类型:动态规划

难度:中等

不同路径 - 图1

解题思路

方法一:动态规划

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。

方法二:组合数学

不同路径 - 图2

代码

方法一

  1. class Solution {
  2. public int uniquePaths(int m, int n) {
  3. int[][] f = new int[m][n];
  4. for (int i = 0; i < m; ++i) {
  5. f[i][0] = 1;
  6. }
  7. for (int j = 0; j < n; ++j) {
  8. f[0][j] = 1;
  9. }
  10. for (int i = 1; i < m; ++i) {
  11. for (int j = 1; j < n; ++j) {
  12. f[i][j] = f[i - 1][j] + f[i][j - 1];
  13. }
  14. }
  15. return f[m - 1][n - 1];
  16. }
  17. }

方法二

  1. class Solution {
  2. public int uniquePaths(int m, int n) {
  3. long ans = 1;
  4. for (int x = n, y = 1; y < m; ++x, ++y) {
  5. ans = ans * x / y;
  6. }
  7. return (int) ans;
  8. }
  9. }