Leetcode62. Unique Paths

Leetcode62. Unique Paths

A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).
How many possible unique paths are there?
在这里插入图片描述
Above is a 7 x 3 grid. How many possible unique paths are there?
Note: m and n will be at most 100.

Example 1:

Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right

Example 2:

Input: m = 7, n = 3
Output: 28
思路一:排列组合

因为机器人到达底右下角,向下m步,向右n步都是固定的,只是出现的顺序不一样。所以求解法,本质上是求了组合数,N = m + n - 2(总共走的步数), k = m - 1(向下的步数)。所以总共的解是 C n k = C m + n − 2 m − 1 = n ! k ! ( n − k ) ! C_{n}^{k} = C_{m+n-2}^{m-1} = \frac{n!}{k!(n-k)!} Cnk=Cm+n2m1=k!(nk)!n!

  • 时间复杂度: O ( m ) O(m) O(m)
  • 空间复杂度: O ( 1 ) O(1) O(1)
Java
public int uniquePaths(int m, int n) {
    int N = n + m - 2; 
    int k = m - 1;  
    long res = 1; 
    for (int i = 1; i <= k; i++)
        res = res * (N - k + i) / i;
    return (int) res; 
}
Python
def uniquePaths(self, m: int, n: int) -> int:
        return int(math.factorial(m+n-2)/math.factorial(m-1)/math.factorial(n-1))
思路二:动态规划

定义:令 dp[i][j] 是到达 (i, j) 的最多路径数
动态方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]
初始化:d[0][j] = d[i][0] = 1
状态压缩:每次只需要记录dp[i-1][j]dp[i][j-1]即可。
在这里插入图片描述

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for (int i = 0; i < n; i++) dp[0][i] = 1;
        for (int i = 0; i < m; i++) dp[i][0] = 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];
            }
        }
        return dp[m - 1][n - 1];  
    }
}
  • 时间复杂度: O ( m ∗ n ) O(m * n) O(mn)
  • 空间复杂度: O ( m ∗ n ) O(m * n) O(mn)

优化一
dp[i][j] = dp[i-1][j] + dp[i][j-1]
pre[i]记录的是dp[i][j-1],即当前行的上一行,在到达行末后让pre=cur来更新到下一行。
cur[]记录的是dp[][j],即当前行,在到达行末后cur开始计算下一行的第二个。cur[0]始终为1,cur[1]开始往右更新行。
完成一个内部循环即更新了一行,然后进行下一个外部循环,即进入计算下一行。

class Solution {
    public int uniquePaths(int m, int n) {
        int[] pre = new int[n];
        int[] cur = new int[n];
        Arrays.fill(pre, 1);
        Arrays.fill(cur,1);
        for (int i = 1; i < m;i++){
            for (int j = 1; j < n; j++){
                cur[j] = cur[j-1] + pre[j];
            }
            pre = cur.clone();
        }
        return pre[n-1]; 
    }
}
  • 时间复杂度: O ( m ∗ n ) O(m * n) O(mn)
  • 空间复杂度: O ( 2 n ) O(2n) O(2n)
例如m = 3,n = 4,初始化pre=[1,1,1,1],cur=[1,1,1,1]。
①i=1,j=1,2,3:cur[1] = 2, cur[2] = 3,cur[3] = 4,第二行更新完成,此时cur=[1,2,3,4],另pre=cur,进入下一行的更新
②i=2,,j=1,2,3:cur[1] = 3, cur[2] = 6, cur[3] = 10,第三行更新完成,结束。

优化二

class Solution {
    public int uniquePaths(int m, int n) {
        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];
    }
}
  • 时间复杂度: O ( m ∗ n ) O(m * n) O(mn)
  • 空间复杂度: O ( n ) O(n) O(n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值