LeetCode UniquePaths

题意

一个机器人目前停留在一个mxn的表格的左上角(如下图所示,标注为’Start’). 这个机器人只能向下或者向右移动.机器人的目标是尽力到达表格的右下角(下图标注为’Finish’). 求:一共有多少条不同的路径可以实现机器人的目的. 注意:m 和 n 均不超过 100.

题解

算法及复杂度(0 ms) 分析题目发现,到达一个点的方法只能是从这个点的上方或者左方.所以问题的解可以尝试通过左边的点的解和上边的解的结合得到. 如何结合得到?如果从开始到达(i, j)这个点的上方点(i - 1, j)的路径数为m, 从开始到达(i,j)点的左方点(i, j - 1)的路径数为n,显然可以得到到达(i, j)的路径数就是 m + n.也就是到达上方点的路径数加上到达左方点的路径数. 由于到达每个左边都有一个路径数,不妨设开始点到达(i, j)点的路径数为dpi. 那么,根据上边的分析有开始点到达(i, j)点的路径数为dp[i][j] = dp[i - 1][j] + dp[i][j - 1].这个方程是显然成立的. 时间复杂度: O(mn),表格中每个位置进行一次计算即可.

算法正确性

正确性证明 以上做法使用的动态规划的思想,下面证明一下本题可以使用动态规划的思想.
一个问题要想使用动态规划进行求解,就需要满足两个条件:
(1)具有最优子结构(2)无后效性.
在本题中,从开始点到达某点的路径数可以看做是从开始点到达某点最多的路径数.如果求从开始点到达某点最多的路径数,需要要求已知开始点到达它上方点的最多路径数和开始点到达它下方点的最多路径数,以此进行转移.因此满足条件(1);
对于条件(2),表明当前决策,也就是dp[i][j] = dp[i - 1][j] + dp[i][j - 1]是不需要通过后边的状态得到的或者说不受后边状态(比如dpi + 1)的影响,显然是满足的. 所以本题可以根据上述状态转移方程进行求解. 举个例子

//输入 m = 2, n = 2
//初始化
dp[0][0:n] = 0, dp[0:m][0] = 0, dp[1][1] = 1
//求解过程
dp[1][2] = dp[0][2] + dp[1][1] = 1
dp[2][1] = dp[1][1] + dp[2][0] = 1
dp[2][2] = dp[1][2] + dp[2][1] = 2
//return 2

CPP代码

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>>dp(m + 1, vector<int>(n + 1));
        for(int i = 0; i <= m; i ++) dp[i][0] = 0;
        for(int j = 0; j <= n; j ++) dp[0][j] = 0;
        
        for(int i = 1; i <= m; i ++) {
            for(int j = 1; j <= n; j ++) {
                if(i == 1 && j == 1) {
                    dp[i][j] = 1;
                } else {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                }
            }
        }
        return dp[m][n];
    }
};

你可能感兴趣的:(leetcode题解)