LeetCode/solutions/62. Unique Paths.md
2019-02-04 19:45:03 +08:00

2.0 KiB
Raw Blame History

62. Unique Paths

思路

思路一

题目要求从网格矩形的左上角移动到右下角共有多少可能的路径,一次移动只能向右或向下。
就是一个简单的递归,设置一个大小为(m + 1)x(n + 1)的数组dp初始值全为0, dp[i][j]代表从左上角到达位置第i行第j列的路径数 则根据题意可知dp[1][1] = 1dp[i][j] += (dp[i - 1][j] + dp[i][j - 1])。最终的返回结果就是dp[m][n]。
时间复杂度O(mn)空间复杂度O(mn)

思路一空间改进版

思路一的空间还有改进空间因为每次计算dp[i][j]时只用到了dp[i - 1][j]dp[i][j - 1],所以我们没必要开那么大一个二维数组

思路二

这题就是之前高中做过的一个数学题。考虑mxn的网格机器人要想到达目的地必须一共向下走m-1步、向右走n-1步顺序不限。
所以这题转换成一个排列组合题: 有两种球分别m-1、n-1个将这些球排成一排一共有多少种排法很明显答案是(m+n-2)!/[(m-1)!(n-1)!]种(即先进行全排列再消序)。
时间复杂度O(min(m, n)), 空间复杂度O(1)

C++

思路一

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>>dp(m + 1, vector<int>(n + 1, 0));
        dp[1][1] = 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][n];
    }
};

思路二

class Solution {
public:
    int uniquePaths(int m, int n) {
        if(m == 1 || n == 1) return 1;
        long long res = 1, tmp = 1;
        if(m < n){ // 保证m > n, 否则可能会溢出
           int mbk = m;
            m = n;
            n = mbk;
        }
        for(int i = m; i <= m + n - 2; i++) res *= i; // 计算 (m + n - 2)! / (m - 1)!
        for(int i = 2; i <= n - 1; i++) tmp *= i; // 计算 (n-1)!
        res /= tmp;
        return (int)res;
    }
};