[C++]LeetCode: 56 Unique Paths

题目:

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?


Above is a 3 x 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

思路:动态规划求解dp[i][j]表示从左上角到(i, j)点的unique path种类数。(求(0,0)到(m-1,n-1)的路径总数)

如果m != 1 && n != 1, 则dp[i][j] = dp[i-1][j] + dp[i][j]; (前一列 + 上一行)。可以化简为dp[j] = dp[j-1] + dp[j]. 参考《[C++]LeetCode: 51 Minimum Path Sum》【情况一

如果m ==1 || n == 1, dp = 1;【情况二】

Attention:

1. 初始化条件 

vector dp(n, 1);

注意该问题和51求最小路径的区别,需要考虑情况二,所以dp[1][] 和dp[][1]都是已确定为1. 直接在动态规划初始条件中设定;

同时循环中,也只需要计算1~m-1行共m-1行,和1~n-1列共n-1列。(第一行和第一列不能计算,如果循环叠加就不能取定值1,如果取for(int i = 1; i <= m; i++), 第一行迭代将得到0,1,2,3,4,...,与实际情况不符合。)

2. 容器大小设定。

vector dp(n, 1);

这道题不需要考虑边界的问题,具体问题具体对待,所以数组大小为n. Minimum Path Sum中需要比较min(dp[ci], dp[ci-1]),需要一个额外的边界值dp[1](比较min(dp[1], INT_MAX)),才能使动态规划进行。本题不需要考虑这种边界问题。只需要将情况而考虑进去。

复杂度:时间复杂度O(MN), 空间O(N)

AC Code:

class Solution {
public:
    int uniquePaths(int m, int n) {
        //动态规划方程,dp[m-1][n-1]表示从top-left(0,0)到m-1,n-1(即bottom-right)的所有unique path
        //dp[i][j] = dp[i-1][j] + dp[i][j-1] 如果存在上一列和上一行
        //可以化简为dp[j] = dp[j-1] + dp[j]
        if(m == 0 || n == 0) return 0;
        
        //第一行应该初始化为1  m=1或n=1,dp为1
        vector dp(n, 1);
        
        //除去第一行,还有m-1行需要计算
        for(int ri = 1; ri < m; ri++)
        {
            //若n=1, dp[0]为1,则不需要计算,只需要计算其余n-1列。
            for(int ci = 1; ci < n; ci++)
            {
                //dp[ci] = dp[ci-1] + dp[ci];
                dp[ci] += dp[ci-1];
            }
        } 
        return dp.back();
    }
};


你可能感兴趣的:(LeetCode)