[LeetCode] 62. 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?

Example 1:

Input: m = 3, n = 7
Output: 28

Example 2:

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 -> Down -> Down
2. Down -> Down -> Right
3. Down -> Right -> Down

Example 3:

Input: m = 7, n = 3
Output: 28

Example 4:

Input: m = 3, n = 3
Output: 6

Constraints:

  • 1 <= m, n <= 100
  • It's guaranteed that the answer will be less than or equal to 2 * 109.

不同路径。

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/unique-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题意是一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径。

这一题也是 DP 的基础题,一定要掌握。这里我提供三种做法,

  • 自上而下(自上而下又叫递归 + memo)
  • 自下而上
  • 节省空间的自下而上

DP自上而下

时间O(mn)

空间O(mn)

Java实现

 1 class Solution {
 2     int[][] memo;
 3     
 4     public int uniquePaths(int m, int n) {
 5         memo = new int[m][n];
 6         return dp(m - 1, n - 1);
 7     }
 8     
 9     private int dp(int i, int j) {
10         if (i == 0 && j == 0) {
11             return 1;
12         }
13         if (i < 0 || j < 0) {
14             return 0;
15         }
16         if (memo[i][j] > 0) {
17             return memo[i][j];
18         }
19         memo[i][j] = dp(i - 1, j) + dp(i, j - 1);
20         return memo[i][j];
21     }
22 }
23 
24 // dp自上而下

 

DP自下而上,先确定矩阵边缘上的点的DP值,然后再考虑中间的点

时间O(mn)

空间O(mn)

Java实现

 1 class Solution {
 2     public int uniquePaths(int m, int n) {
 3         int[][] dp = new int[m][n];
 4         dp[0][0] = 1;
 5         for (int i = 1; i < m; i++) {
 6             dp[i][0] = 1;
 7         }
 8         for (int j = 1; j < n; j++) {
 9             dp[0][j] = 1;
10         }
11         for (int i = 1; i < m; i++) {
12             for (int j = 1; j < n; j++) {
13                 dp[i][j] += dp[i - 1][j];
14                 dp[i][j] += dp[i][j - 1];
15             }
16         }
17         return dp[m - 1][n - 1];
18     }
19 }
20 // dp自下而上

 

节省空间的一维 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]。这个思路非常巧妙,需要多多体会。

时间O(mn)

空间O(n)

 

Java实现

 1 class Solution {
 2     public int uniquePaths(int m, int n) {
 3         int[] res = new int[n];
 4         Arrays.fill(res, 1);
 5         for (int i = 1; i < m; i++) {
 6             for (int j = 1; j < n; j++) {
 7                 res[j] += res[j - 1];
 8             }
 9         }
10         return res[n - 1];
11     }
12 }
13 // 节省空间的自下而上

 

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 };

 

相关题目

62. Unique Paths

63. Unique Paths II

64. Minimum Path Sum

LeetCode 题目总结

posted @ 2020-03-23 09:40  CNoodle  阅读(425)  评论(0编辑  收藏  举报