62. 不同路径——动态规划/排列组合

1.题目

62. 不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

 

示例 1:


输入:m = 3, n = 7
输出:28
示例 2:

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

输入:m = 7, n = 3
输出:28
示例 4:

输入:m = 3, n = 3
输出:6
 

提示:

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

2.自我思路及实现

3.总结思路及实现

动态规划

设f(i,j)代表走到i,j处的所有路径,那么机器人或者向下到达i,j,或者向右到达i, j,那么状态转移方程就是:
f (i , j) = f ( i − 1 , j ) + f ( i , j − 1)
上述方程i, j 不等于0

特例

  • 当i或 j = 0,时,只有一种路径可以到达
  • f(0,0) = 1

优化:

  • 由于结果只与上一行和本行有关,因此可以创建一个一维数组来存储结果
  • cur[j] = cur[j - 1] + cur[j]
  • 未赋值之前右边的cur[j] 始终表示当前行第i行的上一行第j列的值,赋值之后左边的cur[j]表示当前行第i行第j列的值,cur[j-1] 表示当前行第i行第j-1列的值(cur[j-1] 在计算cur[j]之前就已经计算了,所以表示的是当前行而不是上一行

时间:mn
空间:min(m ,n)

class Solution {
    public int uniquePaths(int m, int n) {
        if(m > n)
            return uniquePaths(n, m);
            
        int[] cur = new int[n];
        Arrays.fill(cur, 1);
        for(int i = 1; i < m; i++)
        {
            for(int j = 1; j < n; j++)
            {
                cur[j] += cur[j - 1];
            }
        }
        return cur[n - 1];
    }
}

排列组合

无论哪种路径,总是向下移动m - 1次,向右移动n-1次,那么问题转化为
m - 1个a与n - 1个b共有多少种排列方式 
根据排列组合计算,在 m - 1 + n - 1个位置中找m个位置将a放入,其余位置填上b
C下(m - 1 + n - 1),上( m - 1) 或(n - 1)
在这里插入图片描述
化简为在这里插入图片描述

为了防止乘法时越界,使用long存储结果

时间:min(m, n),与循环次数有关,我们总可以选择m为较小的数
空间:1

class Solution {
    public int uniquePaths(int m, int n) {
        if(m > n)
            return uniquePaths(n, m);
        long ans = 1;
        for (int x = n, y = 1; y <= m - 1; x++, y++) {
            ans = ans * x / y;
        }
        return (int) ans;
    }
}

4.相关知识

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页