2013.12.21 03:19
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.
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
.
Note: m and n will be at most 100.
Solution1:
This problem is a variation from "LeetCode - Unique Paths", only difference in that there're some grids defined as impenetrable obstacles.
I haven't come up with a solution using combinatorics. So I just did it the old-school way, dynamic programming with recurrence relation as:
a[x][y] = b[x][y] ? 0 : a[x - 1][y] + a[x][y - 1];
where a[x][y] means the number of unique paths to (x, y), b[x][y] = 1 means (x, y) is an obstacle, while 0 for free space.
Time complexity is O(m * n), space complexity is O(m * n).
Accepted code:
1 // 1WA, 1AC 2 class Solution { 3 public: 4 int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) { 5 // IMPORTANT: Please reset any member data you declared, as 6 // the same Solution instance will be reused for each test case. 7 int m, n; 8 9 m = obstacleGrid.size(); 10 if(m <= 0){ 11 return 0; 12 } 13 14 n = obstacleGrid[0].size(); 15 16 int **arr = nullptr; 17 int i, j; 18 19 arr = new int*[m]; 20 for(i = 0; i < m; ++i){ 21 arr[i] = new int[n]; 22 } 23 24 arr[0][0] = obstacleGrid[0][0] ? 0 : 1; 25 for(i = 1; i < m; ++i){ 26 // 1WA here, arr[i][0] = obstacleGrid[i][0] ? 0 : obstacleGrid[i - 1][0]; 27 // arr[i][0] = obstacleGrid[i][0] ? 0 : arr[i - 1][0]; 28 arr[i][0] = obstacleGrid[i][0] ? 0 : arr[i - 1][0]; 29 } 30 for(i = 1; i < n; ++i){ 31 arr[0][i] = obstacleGrid[0][i] ? 0 : arr[0][i - 1]; 32 } 33 for(i = 1; i < m; ++i){ 34 for(j = 1; j < n; ++j){ 35 arr[i][j] = obstacleGrid[i][j] ? 0 : arr[i - 1][j] + arr[i][j - 1]; 36 } 37 } 38 39 int res = arr[m - 1][n - 1]; 40 for(i = 0; i < m; ++i){ 41 delete[] arr[i]; 42 } 43 delete[] arr; 44 45 return res; 46 } 47 };
Solution2:
Space complexity can be optimized to linear, using 2 rows instead of m rows of extra space.
Time complexity is O(m * n), space complexity is O(n).
Accepted code:
1 // 1AC, very nice 2 class Solution { 3 public: 4 int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) { 5 // IMPORTANT: Please reset any member data you declared, as 6 // the same Solution instance will be reused for each test case. 7 int m, n; 8 9 m = obstacleGrid.size(); 10 if(m <= 0){ 11 return 0; 12 } 13 14 n = obstacleGrid[0].size(); 15 16 int **arr = nullptr; 17 int i, j; 18 int flag = 0; 19 20 arr = new int*[2]; 21 for(i = 0; i < 2; ++i){ 22 arr[i] = new int[n]; 23 } 24 25 flag = 0; 26 arr[flag][0] = obstacleGrid[0][0] ? 0 : 1; 27 for(i = 1; i < n; ++i){ 28 arr[flag][i] = obstacleGrid[0][i] ? 0 : arr[flag][i - 1]; 29 } 30 for(i = 1; i < m; ++i){ 31 flag = !flag; 32 arr[flag][0] = obstacleGrid[i][0] ? 0 : arr[!flag][0]; 33 for(j = 1; j < n; ++j){ 34 arr[flag][j] = obstacleGrid[i][j] ? 0 : arr[!flag][j] + arr[flag][j - 1]; 35 } 36 } 37 38 j = arr[flag][n - 1]; 39 for(i = 0; i < 2; ++i){ 40 delete[] arr[i]; 41 } 42 delete[] arr; 43 44 return j; 45 } 46 };