leetcode 62. Unique Paths
这道题用动态规划解答。
按照代码随想录介绍的动态规划五部曲来分析。
第一步,明确dp数组的含义,包括数组下标的含义和数组取值的含义。
定义一个m*n的二维数组path。path[i][j]表示从原点(0,0)到(i,j)的不同路径的数目。题目给出m*n的网格,要求到达右下角(m-1,n-1)的不同路径数目,就等价于求path[m-1][n-1]。
第二步,明确递推公式
分析前先约定,行号和列号都是从0开始起算的。分析发现,当row>=1并且column>=1时,要到达(row,column),有两种可能,要么是从它正上面的相邻位置(row-1,column)向下走一步到达的,要么是从它的正左边的相邻位置(row,column-1)向右走一步到达的。因此得到如下递推公式:
path[row][column] = path[row-1][column] + path[row][column],其中row>=1,column>=1.
第三步,明确怎么初始化dp数组
显然,path[0][0]应该等于1,含义是从原点到达原点,只有一条路径,那就是一步也不走。
从第二步的分析就可以发现,所有第0行的位置都没有上一行位置,所有第0列的位置都没有左边一列的位置。也就是说,除了原点,要到达所有第0行的位置,只有一种路径,那就是从它的左边一路往右走。除了原点,要达到所有第0列的位置,只有一种路径,那就是从它的上面一路往下走。
因此,除了要把path[0][0]初始化为1之外,还需要把path[0][column](0<column<=n-1),以及path[row][0](0<row<=m-1)初始化为1。
第四步,明确遍历顺序
本题显然应该将行号和列号都从小到大遍历,含义是从原点出发一步步到达目的地。遍历的时候行号从1到m-1,列号从1到n-1。
第五步,打印dp数组的值
可以用题目给的例子,模拟一下,验证前面的分析是否有误。
代码
class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> path;path.resize(m);for(int i = 0;i < m;i++) path[i].resize(n);//path[i][j]表示从原点(0,0)到(i,j)的不同路径数目for(int i = 0;i < m;i++) path[i][0] = 1;for(int i = 0;i < n;i++) path[0][i] = 1;for(int row = 1;row < m;row++){for(int column = 1;column < n;column++){path[row][column] = path[row-1][column]+path[row][column-1];}}return path[m-1][n-1];}
};