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