之所以将这三道题放在一起,是因为这三道题非常类似。
1. Minimum Path Sum
题目要求:
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
该题解答参考自一博文。
设dp[i][j]表示从左上角到grid[i][j]的最小路径和。那么dp[i][j] = grid[i][j] + min( dp[i-1][j], dp[i][j-1] );
下面的代码中,为了处理计算第一行和第一列的边界条件,我们令dp[i][j]表示从左上角到grid[i-1][j-1]的最小路径和,最后dp[rows][cols]是我们所求的结果
1 int minPathSum(vector<vector<int>>& grid) { 2 int rows = grid.size(); 3 if(rows == 0) 4 return 0; 5 int cols = grid[0].size(); 6 7 vector<vector<int> > dp(rows + 1, vector<int>(cols + 1, INT_MAX)); 8 dp[0][1] = 0; 9 for(int i = 1; i < rows + 1; i++) 10 for(int j = 1; j < cols + 1; j++) 11 dp[i][j] = grid[i - 1][j - 1] + min(dp[i][j - 1], dp[i - 1][j]); 12 13 return dp[rows][cols]; 14 }
注意到上面的代码中dp[i][j] 只和上一行的dp[i-1][j]和上一列的dp[i][j-1]有关,因此可以优化空间为O(n)(准确来讲空间复杂度可以是O(min(row,col)))
1 int minPathSum(vector<vector<int>>& grid) { 2 int rows = grid.size(); 3 if(rows == 0) 4 return 0; 5 int cols = grid[0].size(); 6 7 vector<int> dp(cols + 1, INT_MAX); 8 dp[1] = 0; 9 for(int i = 1; i < rows + 1; i++) 10 for(int j = 1; j < cols + 1; j++) 11 dp[j] = grid[i-1][j-1] + min(dp[j-1], dp[j]); 12 13 return dp[cols]; 14 }
2. 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 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
这道题的解答跟上一道题是非常类似的,程序如下:
1 int uniquePaths(int m, int n) { 2 if(m == 0 && n == 0) 3 return 0; 4 5 vector<vector<int> > dp(m, vector<int>(n, 1)); 6 for(int i = 1; i < m; i++) 7 for(int j = 1; j < n; j++) 8 dp[i][j] = dp[i-1][j] + dp[i][j-1]; 9 10 return dp[m-1][n-1]; 11 }
优化空间程序:
1 int uniquePaths(int m, int n) { 2 if(m == 0 && n == 0) 3 return 0; 4 5 vector<int> dp(n, 1); 6 for(int i = 1; i < m; i++) 7 for(int j = 1; j < n; j++) 8 dp[j] = dp[j-1] + dp[j]; 9 10 return dp[n - 1]; 11 }
3. 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.
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.
这道题跟上一道题基本一致,不同的地方在于我们需要将能到达存在obstacle的地方的路径数置为0。程序如下:
1 int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { 2 int rows = obstacleGrid.size(); 3 if(rows == 0) 4 return 0; 5 6 int cols = obstacleGrid[0].size(); 7 if(cols == 0) 8 return 0; 9 10 vector<vector<int> > dp(rows, vector<int>(cols, 1)); 11 int i = 0; 12 while(i < rows) 13 { 14 if(obstacleGrid[i][0] == 1) 15 while(i < rows) 16 { 17 dp[i][0] = 0; 18 i++; 19 } 20 i++; 21 } 22 int j = 0; 23 while(j < cols) 24 { 25 if(obstacleGrid[0][j] == 1) 26 while(j < cols) 27 { 28 dp[0][j] = 0; 29 j++; 30 } 31 j++; 32 } 33 34 for(i = 1; i < rows; i++) 35 for(j = 1; j < cols; j++) 36 { 37 if(obstacleGrid[i][j] == 1) 38 dp[i][j] = 0; 39 else 40 dp[i][j] = dp[i-1][j] + dp[i][j-1]; 41 } 42 43 return dp[rows-1][cols-1]; 44 }