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<int> 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<int> 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<int> 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();
}
};