[LintCode] Unique Paths II
Follow up for "Unique Paths":
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.
m and n will be at most 100.
Example
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[ [0,0,0], [0,1,0], [0,0,0] ]
The total number of unique paths is 2
.
Solution 1. Recursion
1 public class Solution { 2 private int totalPaths = 0; 3 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 4 if(obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0){ 5 return 0; 6 } 7 findPaths(obstacleGrid, 0, 0); 8 return totalPaths; 9 } 10 private void findPaths(int[][] grid, int x, int y){ 11 if(!isInBound(grid, x, y) || grid[x][y] == 1){ 12 return; 13 } 14 if(x == grid.length - 1 && y == grid[0].length - 1){ 15 totalPaths++; 16 return; 17 } 18 findPaths(grid, x + 1, y); 19 findPaths(grid, x, y + 1); 20 } 21 private boolean isInBound(int[][] grid, int x, int y){ 22 return x >= 0 && x < grid.length && y >= 0 && y < grid[0].length; 23 } 24 }
Solution 2. Dynamic Programming, O(m * n) runtime, O(m * n) space
1 public class Solution { 2 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 3 if(obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0 || obstacleGrid[0][0] == 1) { 4 return 0; 5 } 6 int m = obstacleGrid.length; 7 int n = obstacleGrid[0].length; 8 int[][] T = new int[m][n]; 9 int i = 0, j = 0; 10 for(; i < m; i++) { 11 if(obstacleGrid[i][0] == 1) { 12 break; 13 } 14 T[i][0] = 1; 15 } 16 for(; j < n; j++) { 17 if(obstacleGrid[0][j] == 1) { 18 break; 19 } 20 T[0][j] = 1; 21 } 22 for(i = 1; i < m; i++) { 23 for(j = 1; j < n; j++) { 24 if(obstacleGrid[i][j] == 1) { 25 T[i][j] = 0; 26 } 27 else { 28 T[i][j] = T[i - 1][j] + T[i][j - 1]; 29 } 30 } 31 } 32 return T[m - 1][n - 1]; 33 } 34 }
Solution 3. Dynamic Programming with space optimization, O(m * n) runtime, O(n) space
1 public class Solution { 2 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 3 if(obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0){ 4 return 0; 5 } 6 int[][] T = new int[2][obstacleGrid[0].length]; 7 int i = 0; 8 for(; i < obstacleGrid[0].length; i++){ 9 if(obstacleGrid[0][i] == 1){ 10 break; 11 } 12 T[0][i] = 1; 13 } 14 for(; i < obstacleGrid[0].length; i++){ 15 T[0][i] = 0; 16 } 17 boolean reachable = (obstacleGrid[0][0] == 0 ? true : false); 18 for(int j = 1; j < obstacleGrid.length; j++){ 19 if(reachable && obstacleGrid[j][0] == 0){ 20 T[j % 2][0] = 1; 21 } 22 else{ 23 reachable = false; 24 T[j % 2][0] = 0; 25 } 26 for(int k = 1; k < obstacleGrid[0].length; k++){ 27 if(obstacleGrid[j][k] == 1){ 28 T[j % 2][k] = 0; 29 } 30 else{ 31 T[j % 2][k] = T[(j - 1) % 2][k] + T[j % 2][k - 1]; 32 } 33 } 34 } 35 return T[(obstacleGrid.length - 1) % 2][obstacleGrid[0].length - 1]; 36 } 37 }
Related Problems
Unique Paths
Unique Paths III