力扣小白刷题之62题不同路径
题目描述
一个机器人位于一个 m * n 网格的左上角(“start”)。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(“Finish”)
请问总共个有多少条不同的路径?
思路
动态规划
- 使用二维数组 dp 来存储答案,dp[i][j] 的值是从起始点(0, 0) 走到 (i, j) 的路径数。
确定状态转移方程:
- 需要根据状态转移方程来求出dp[i][j],而机器人每次只能从上边或左边来,所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。
确定边界条件:
- dp[i][j] = dp[i - 1][j] + dp[i][j - 1],当 i == 0 或 j == 0时会越界,而 i == 0或 j == 0 是最上面一行或最左边一列。在最上面一行只能一直向右走,最左边一列只能一直向下走,所以 dp[0][j] 的值全是 1,dp[i][0] 的值也都是 1。所以第一列和第一行的值全是1。
返回值:
- 最后返回右下角的值dp[n - 1][m - 1]
时间复杂度: O(mn)
空间复杂度: O(mn)
代码
优化1
行列两层循环中的循环体 cur[j] = cur[j - 1] + pre[j]
其中cur[j] 表示从起点到 第 i 行第 j 列 的路径数,它等于第 i 行 第 j - 1 列的路径数cur[j - 1] 加上 第 i - 1 行第 j 列的路径数pre[j]。内层循环一次后即计算完了第 i 行各列的值,在计算下一行第 i + 1 行之前执行pre = cur.clone();
即第 i 行的值就是 第 i + 1 行的前一行,两层循环完以后最终要到达的终点的行的值存于 pre 数组中,所以取出pre[n - 1] 即可。
将空间复杂度优化为O(2n)
** 代码**
优化2
cur[j] = cur[j - 1] + cur[j] ;
赋值前 右边的 cur[j] 始终表示当前行第 i 行的上一行第 j 列的值,赋值后 左边的cur[j] 表示当前行第 i 行 第 j 列的值,cur[j - 1]表示当前行第 i 行第 j - 1列的值(cur[j - 1]在计算 cur[j] 之前就已经计算了,所以表示的是当前行而不是上一行),思路与优化1相同,除了少用一个数组。
内循环一次后即计算完成了第 i 行 各列的值,两层循环完以后最终要到达的终点的行的值存于cur数组中,取出cur[n - 1]即可。
将空间复杂度优化为:O(n)
代码