zoukankan      html  css  js  c++  java
  • LeetCode 数组:62. 不同路径(动态规划 带记忆的递归)

    ,接下来

    在没有接触过动态规划之前,是这样思考这个题的。

    首先想到的就是递归中青蛙跳台阶的问题,自然想到递归。就使用原函数 int uniquePaths(int m, int n)

    • 函数的作用,遵循规则的情况下,有多少中途径到达坐标为(m-1,n-1)的位置
    • 递归终止条件:原点(m=n=1),函数返回1,如果m==0||n==0也是返回1(只有一种)
    • 递归关系:uniquePaths(m,n)=uniquePaths(m-1,n)+uniquePaths(m,n-1)

    代码完成如下:

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

    然而超时了。。。

    递归有重复计算的问题,在很多格子中,明明曾经已经计算过结果,但是碰到仍然向后继续递归了:

    加一个数组,用于保存已经计算的结果

    class Solution {
        int[][] dp = new int[100][100];
        public int uniquePaths(int m, int n) {
            return cycle(m-1,n-1);
        }
        public int cycle(int i,int j){
            if(i == 0 || j == 0) return 1;
            if(dp[i][j] != 0) return dp[i][j];
            dp[i][j] = cycle(i-1,j)+cycle(i,j-1);
            return dp[i][j];
        }
    }

    通过接下来看动态规划的算法。

    动态规划是正着推,而且有一个用于存放结果的一维/二维数组,大部分问题是二维的。

    首先需要确认该问题是否符合动态规划解题要求
    动态规划适合解决的问题模型符合"一个模型三个特性"
    一个模型可以概括为:多阶段决策最优解模型; 本题目第一行是已经定好了都是1,
    在第二行的时候,每个方格的值都是该方格左边的格和该方格上边的格的总和,以此类推,满足.
    • 特性1:最优子结构;每个阶段的状态或值都是通过前面阶段的状态或值推导出来的,满足.
    • 特性2:无后效性;每个阶段的状态值一旦确定之后,是不受后面阶段状态值所影响的,满足.
    • 特性3:重复子问题;从递归解法中就能看出来有重复子问题的计算,满足.
     
    接下来,该分析如何套用动态规划解题步骤
    首先,定义二维数组保存路径条数,按照递归中分析得出第一行和第一列都是1,所以二维数组直接定义成如此
    然后分阶段阶段,每一横行的处理就是一个阶段,通过上一行就能推导出下一行的状态值
    在每一个阶段中,同一行中的方格,是其左边方格的值加上一行方格的总和
    最后返回二维数组最后一个元素的值即可.
    class Solution {
        public int uniquePaths(int m, int n) {
            int [][] dp = new int[m+1][n+1];
            //
            for(int i = 1;i<m+1;i++){
                //
                for(int j = 1;j<n+1;j++){
                    if(i == 1 && j == 1){
                        dp[1][1] = 1;
                    }else{
                        //状态转移方程
                        dp[i][j] = dp[i-1][j] + dp[i][j-1];
                    }
                }
            }
            return dp[m][n];
        }
    }

    这样的时间复杂度和空间复杂度都是om*n

    有优化的办法,把空间复杂度优化为O2n或者On

    优化一:将一个表优化成了表中我们需要的两行

    优化二:在优化一的基础上,将两行优化成了我们需要的当前行,因为cur未更新前保存的结果是上一行的结果

    另外,这道题其实直接排列组合就能做:

  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/take-it-easy/p/13445490.html
Copyright © 2011-2022 走看看