不同路径。题意是一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径。
Example 1:
Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Right -> Down 2. Right -> Down -> Right 3. Down -> Right -> RightExample 2:
Input: m = 7, n = 3 Output: 28
这一题也是DP的基础题,是由递归衍生出来的DP。这一题的DP可以是一维的也可以是二维的。
首先是二维的DP,创建一个二维数组和input数组同样大小,并初始化第一行和第一列,因为到达第一行和第一列的任何一个坐标的最短路径只有一种。对于除了第一行和第一列的其他坐标而言,到达这个坐标的方式有两种,要不然是从左边过来,要不然是从上面过来,所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。
时间O(mn)
空间O(mn)
Java实现
1 class Solution { 2 public int uniquePaths(int m, int n) { 3 int[][] res = new int[m][n]; 4 for (int i = 0; i < m; i++) { 5 res[i][0] = 1; 6 } 7 for (int j = 0; j < n; j++) { 8 res[0][j] = 1; 9 } 10 for (int i = 1; i < m; i++) { 11 for (int j = 1; j < n; j++) { 12 res[i][j] = res[i - 1][j] + res[i][j - 1]; 13 } 14 } 15 return res[m - 1][n - 1]; 16 } 17 }
再来是一维DP。一维DP的思路是逐行扫描。首先初始化一个长度为n的数组,并初始化第一个坐标为1(也就是坐标上0, 0的位置)。接着往右边扫描,每一个坐标的值是当前位置的DP值 + 他左边一个位置的DP值。根据下图跑一下代码,第7行,第一遍跑的时候,一开始res[j] = res[1] = 0 + res[0] = 0 + 1 = 1;接着res[2] = 0 + 1 = 1。以此类推得到第一行的dp值是[1, 1, 1, 1, 1, 1]。再遍历第二行,得到[1, 2, 3, 4, 5, 6];第三行[1, 3, 6, 10, 15, 21]和第四行[1, 4, 10, 20, 35, 56]。这个思路非常巧妙,需要多多体会。
已经得到了[1, 2, 3, 4, 5, 6]。
时间O(mn)
空间O(n)
Java实现
1 class Solution { 2 public int uniquePaths(int m, int n) { 3 int[] res = new int[n]; 4 res[0] = 1; 5 for (int i = 0; i < m; i++) { 6 for (int j = 1; j < n; j++) { 7 res[j] = res[j] + res[j - 1]; 8 } 9 } 10 return res[n - 1]; 11 } 12 }
JavaScript实现
1 /** 2 * @param {number} m 3 * @param {number} n 4 * @return {number} 5 */ 6 var uniquePaths = function (m, n) { 7 let res = new Array(n).fill(0); 8 res[0] = 1; 9 for (let i = 0; i < m; i++) { 10 for (let j = 1; j < n; j++) { 11 res[j] = res[j] + res[j - 1]; 12 } 13 // console.log(res); 14 } 15 return res[n - 1]; 16 };