• 62:不同路径(C++)


    题目地址:https://leetcode-cn.com/problems/unique-paths/

    题目描述

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?

    提示:

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

    题目示例

    示例 1:

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

    输入: m = 7, n = 3
    输出: 28

    解题思路

    分析题目可知,到达终点Finish,可以看作是终点的前一列或者前一行的格子,递归式具体可表示为arr[m][n]=arr[m-1][n]+arr[m][n-1]。知道有些同学看不明白,分享一个图,如下

    思路1:递归。对题目给的问题采用自顶向下的思想,拆分为若干子问题求解,但存在子问题的重复求解问题,时间复杂度O(2^mn);

    思路2:记忆化搜索。该方法是对递归的方法进行优化,使用数组存储已经求解过的路径避免重复,时间复杂度O(nn),空间复杂度O(mn);

    思路3:动态规划。将原问题拆分为若干子问题,然后对每个子问题进行求解,并将结果进行保存,从而避免了子问题的重复求解,时间复杂度O(mn),空间复杂度O(mn)。在这里,我们使用二维数组dp来存储最终结果,其中dp[i][j]表示从起点(0,0)走到(i,j)的路径数。根据题目可知,机器人只能向下或者向右,所以dp[i][j]的值就等于第i行第j列这个格子上面的那个格子的路径数加上左边那个格子的路径数,即状态转移方程为dp[i][j]=dp[i-1][j]+dp[i][j-1],因为这两个格子都可以走到第i行第j列的这个格子。

    思路4:对思路3进行优化,主要是优化空间复杂度,因为在思路3中dp数组存储了所有格子的路径信息,我们可以使用一维数组dp来存储最终结果,即当前行格子的信息,其中dp[j]=dp[j]+dp[j-1]为递归表达式。通俗讲,也就是将每一行当作一个动态规划处理,第一行初始化为全1,即路径数为dp[0]=1,然后dp[1]为第二行路径数,即j=1时的路径数,而dp[1]等于上一行数加上当前行元素的值,即dp[1]=dp[0]+dp[1]=2,j=2时,dp[2]=上一行元素的值dp[2]+dp[2-1]=1+2=3,以此类推,可得dp[j]=dp[j]+dp[j-1]。

    相似题目还有63、980。

    程序源码

    思路1

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            if(m <= 0 || n <= 0) return 0;
            if(m == 1 && n == 1) return 1;
            return uniquePaths(m - 1, n) + uniquePaths(m, n - 1);
        }
    };

    思路2

    class Solution {
    public:
        int arr[101][101] = {0};
        int uniquePaths(int m, int n) {
            if(m <= 0 || n <= 0) return 0;
            if(m == 1 && n == 1) return 1;
            if(arr[m][n] > 0) return arr[m][n];
            arr[m - 1][n] = uniquePaths(m - 1, n);
            arr[m][n - 1] = uniquePaths(m, n - 1);
            arr[m][n] = uniquePaths(m - 1, n) + uniquePaths(m, n - 1);
            return arr[m][n];
        }
    };

    思路3

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            vector<vector<int>> dp(m, vector<int>(n, 0));
            for(int i = 0; i < m; i++) 
            {
                dp[i][0] = 1; //初始化第一列路径
            }
            for(int j = 0; j < n; j++)
            {
                dp[0][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]; //到达Finish格子的路径数目
        }
    };

    空间复杂度优化

    class Solution {
    public:
        int uniquePaths(int m, int n) {
            vector<int> dp(n, 1);
            for(int i = 1; i < m; i++)
            {
                for(int j = 1; j < n; j++)
                {
                    dp[j] += dp[j - 1]; //状态转移方程
                }
            }
            return dp[n - 1]; //到达Finish格子的路径数目
        }
    };

    参考文章

    https://leetcode-cn.com/problems/unique-paths/solution/java-jian-dan-ming-liao-de-dong-tai-gui-hua-qiu-ji/

    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    使用dom4j来处理xml的一些常用方法
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/wzw0625/p/13531496.html
Copyright © 2020-2023  润新知