码迷,mamicode.com
首页 > 其他好文 > 详细

Unique Paths 系列

时间:2018-10-03 00:51:03      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:top   des   HERE   line   二维数组   使用   obs   desc   either   

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 系列

标签:top   des   HERE   line   二维数组   使用   obs   desc   either   

原文地址:https://www.cnblogs.com/boris1221/p/9738596.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!