Unique Paths 系列

Posted boris1221

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unique Paths 系列相关的知识,希望对你有一定的参考价值。

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?

技术分享图片
Above is a 7 x 3 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

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 -> Right

Example 2:

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

 分析:题目比较简单,要求找一个矩阵从左上角到右下角有多少条路,注意只能向右向下走。
用动态规划求解,三要素如下:
1、dp[i][j]表示到[i][j]位置的路径数目
2、初始化:dp[i][0] = 1 dp[0][j] = 1
3、状态转移方程:到[i][j]位置可以走的路径是[i-1][j]和[i][j-1]之和
dp[i][j] = dp[i-1][j] + dp[i][j-1]
代码如下:
 1 class Solution {
 2     public int uniquePaths(int m, int n) {
 3         int M=n;
 4         int N=m;
 5         int[][] dp = new int[M][N];
 6 
 7         dp[0][0] = 1;
 8         for ( int j = 1 ; j < N ; j ++ ) dp[0][j] = 1;
 9         for ( int i = 1 ; i < M ; i ++ ) dp[i][0] = 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]+dp[i][j-1];
14             }
15         }
16         return dp[M-1][N-1];
17     }
18 }

 

Unique Paths II

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).

Now consider if some obstacles are added to the grids. How many unique paths would there be?

技术分享图片

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

Note: m and n will be at most 100.

Example 1:

Input:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
Output: 2
Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

 分析:这个题比上一个多了障碍条件,也就是当obstacleGrid[i][j]==1时,这个路时不通的。因此这里只需要比上一个题目增加比较节点值是否为1这个判断条件。同时这里要注意如果obstacleGrid[i][j]==1时,对应的dp[i][j]为0。
代码如下:
 1 class Solution {
 2     public int uniquePathsWithObstacles(int[][] obstacleGrid) {
 3         int M=obstacleGrid.length;
 4         int N=obstacleGrid[0].length;
 5         int[][] dp = new int[M][N];
 6 
 7         dp[0][0] = obstacleGrid[0][0] == 0?1:0;
 8         for ( int j = 1 ; j < N ; j ++ ) {
 9             if( obstacleGrid[0][j-1] == 0 && obstacleGrid[0][j] == 0) dp[0][j] = 1;
10             else break;
11         }
12         for ( int i = 1 ; i < M ; i ++ ) {
13             if( obstacleGrid[i-1][0] == 0 && obstacleGrid[i][0] == 0) dp[i][0] = 1;
14             else break;
15         }
16 
17         for ( int i = 1 ; i < M ; i ++ ){
18             for ( int j = 1 ; j < N ; j ++ ){
19                 if (obstacleGrid[i][j] == 1) {
20                     dp[i][j] = 0;
21                     continue;
22                 }
23                 if ( obstacleGrid[i-1][j] == 1 && obstacleGrid[i][j-1] == 0) dp[i][j] = dp[i][j-1];
24                 else if (obstacleGrid[i-1][j] == 0 && obstacleGrid[i][j-1] == 1) dp[i][j] = dp[i-1][j];
25                 else if (obstacleGrid[i-1][j] == 0 && obstacleGrid[i][j-1] == 0) dp[i][j] = dp[i-1][j]+dp[i][j-1];
26                 else dp[i][j] = 0;
27             }
28         }
29         //for ( int i = 0 ; i < M ; i ++ ){
30         //    for ( int j = 0 ; j < N ; j ++ ){
31         //        System.out.print(dp[i][j] + "   ");
32         //    }
33         //    System.out.println();
34         //}
35         return dp[M-1][N-1];
36     }
37 }

    运行时间1ms,击败50.34%。还不是很满意,主要是代码比较繁琐,需要进行很多次判断。

参考了高票答案,果然是巧妙的方法,将二维dp变化成一维dp。

在状态转移方程中,我们只需要找到dp[i][j]与dp[i-1][j]、dp[i][j-1]的关系,不需要存储整个二维数组。因此这里就可以使用一维数组dp[j] = dp[j] + dp[j - 1]作为状态转移方程,dp[j]与dp[i-1][j]相关,dp[j-1]与dp[i][j-1]相关。

 1 public int uniquePathsWithObstacles(int[][] obstacleGrid) {
 2     int width = obstacleGrid[0].length;
 3     int[] dp = new int[width];
 4     dp[0] = 1;
 5     for (int[] row : obstacleGrid) {
 6         for (int j = 0; j < width; j++) {
 7             if (row[j] == 1)
 8                 dp[j] = 0;
 9             else if (j > 0)
10                 dp[j] += dp[j - 1];
11         }
12     }
13     return dp[width - 1];
14 }

 

 

以上是关于Unique Paths 系列的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-62. Unique Paths

Unique Paths

刷题62. Unique Paths

LeetCode Unique Paths

62. Unique Paths

Unique Paths II