62. Unique Paths-Leetcode

我的想法:递归

根据观察,走到最后一步前到达最后一格的上方或者左边。所以规律为uniquePaths(m,n)=uniquePaths(m-1,n)+uniquePaths(m,n-1),因此可以得到如下代码:

class Solution {
public:
    int uniquePaths(int m, int n) {
        int result;
        if (m==1||n==1)
            return 1;
        else
        {
            result=uniquePaths(m-1,n)+uniquePaths(m,n-1);//动态规划 
            return result;
        } 
    }
};

运行结果:有部分用例超时

我的AC算法:动态规划

之前的递归算法没有保留中间子问题的结果,每次都需要调用和重新计算,可以采用动态规划进行优化。保存中间子问题结果,所以规模大一点的时候动态规划效果好。

class Solution {
public:
    int uniquePaths(int m, int n) {
        int dp[m+1][n+1]; //为了d[m][n]保存的是uniquePaths的结果,不从0开始使用
        for(int i=1;i<=m;i++)
            dp[i][1]=1;
        for(int j=1;j<=n;j++)
            dp[1][j]=1;
        for(int i=2;i<=m;i++)
            for(int j=2;j<=n;j++)
        {
            dp[i][j]=dp[i-1][j]+dp[i][j-1];
        }
        return dp[m][n];
        
    }
};

最优解法

类似的思想,但是只保留一个一维数组,因为每次更新时dp[j] += dp[j - 1];,更新之前dp[j]为上一行对应列的值,dp[j-1]为本行左边一列的值,相当于按行进行更新。
back() 函数返回当前vector最末一个元素的引用。

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector dp(n + 1, 0);//这一步的初始化巧妙地将边界问题解决了,左边界dp[0]和上边界dp初始化的值,将 dp[j] += dp[j - 1];可能的边界问题考虑进去了
        dp[1] = 1;
        
        for (int i = 0; i < m; ++i) {//行数
            for (int j = 1; j <= n; ++j) {//列数
                dp[j] += dp[j - 1];
            }
        }
        return dp.back();
    }
};

你可能感兴趣的:(62. Unique Paths-Leetcode)