题目
分析
dp[i][j] 表示从(0,0)到(i,j)有多少条路径。对dp数组初始化,每次移动只能向右或者向下,对第0行和第0列初始化。如果第0 行或者第0列某个位置上第一次出现了障碍物,那么之后的位置都无法走到。动态转移方程为:如果没有障碍物dp[i][j] = dp[i - 1][j] + dp[i][j - 1],如果有障碍物,dp[i][j] = 0,说明无法走到该位置。
代码
1 class Solution { 2 public: 3 int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { 4 int m = obstacleGrid.size(),n = obstacleGrid[0].size(); 5 vector<vector<int>>dp(m,vector<int>(n)); 6 7 for(int j = 0;j < n;j++){ 8 if(obstacleGrid[0][j] == 0) dp[0][j] = 1; 9 else{ 10 while(j <n){ 11 dp[0][j] =0; 12 j++; 13 } 14 } 15 } 16 for(int i = 0;i < m;i++){ 17 if(obstacleGrid[i][0] == 0) dp[i][0] = 1; 18 else{ 19 while(i <m){ 20 dp[i][0] =0; 21 i++; 22 } 23 } 24 } 25 for(int i = 1;i < m;i++){ 26 for(int j = 1;j < n;j++){ 27 if(obstacleGrid[i][j] == 0) dp[i][j] = dp[i-1][j] + dp[i][j-1]; 28 else dp[i][j] =0 ; 29 } 30 } 31 return dp[m-1][n-1]; 32 33 } 34 };
简化下
1 class Solution { 2 public: 3 int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { 4 int m = obstacleGrid.size(),n = obstacleGrid[0].size(); 5 vector<vector<int>>dp(m,vector<int>(n,0)); 6 //初始化第0行 7 for(int j = 0;j < n && obstacleGrid[0][j] == 0;j++){ 8 dp[0][j] = 1; 9 } 10 for(int i = 0;i < m && obstacleGrid[i][0] == 0;i++){ 11 dp[i][0] = 1; 12 } 13 for(int i = 1;i < m;i++){ 14 for(int j = 1;j < n;j++){ 15 if(obstacleGrid[i][j] == 0) dp[i][j] = dp[i-1][j] + dp[i][j-1]; 16 } 17 } 18 return dp[m-1][n-1]; 19 20 } 21 };
时间复杂度O(m * n) ,空间复杂度O(m * n)