LeetCode.62.不同路径

LeetCode.62.不同路径

难度:medium

LeetCode.62.不同路径_第1张图片

LeetCode.62.不同路径_第2张图片

 方法:动态规划和排列组合

Java:

动态规划:

很清晰的思路,哥么把注释写的明明白白;

class Solution {
    public int uniquePaths(int m, int n) {
        if (m <= 0 || n <= 0) {
            return 1;
        }
        //dp[i][j]表示从(0,0)到(i,j)有多少种方法
        int[][] dp = new int[m + 1][n + 1];
        //初始化,dp[0][j], dp[i][0]为1
        for (int i = 0; i <= m; i++) {
            dp[i][0] = 1;
        }
        for (int j = 0; j <= n; j++) {
            dp[0][j] = 1;
        }
        //递推公式:dp[i][j] = dp[i - 1][j] + dp[i][j - 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(n^2)
  • 空间复杂度:O(n^2)

优化:可以发现每个dp[i][j]的状态只与本行和上一行有关,可以把二维数组优化成两个一维数组,利用滑动窗口的思想来解决;空间复杂度可以优化到O(n);

排列组合:

从(0,0) 到达(m-1,n-1)需要移动m+n-2步,其中向右n-1步,向下m-1步,于是变成了一道愉快的排列组合:

LeetCode.62.不同路径_第3张图片

class Solution {
    public int uniquePaths(int m, int n) {
        long ans = 1;        //注意是long!!!!
        for (int i = 1 ; i <= n - 1; i++) {
            ans = ans * (m - 1 + i) / i;
        }
        return (int)ans;
    }
}

注意:题目的数据是小于2*10^9,int类型显然不够(215612316),所以我们用long类型来存;

害得我找了好久,可恶!

 nice!

你可能感兴趣的:(#,动态规划,LeetCode,leetcode,动态规划,算法)