思路
易错点:初始化的时候,第一行,若有一列是 有障碍物的,那么后面的dp数组的值都为0,因为无法到达,这一列后面的格子只能通过向右走到达,而左边如果有障碍物,那么 右边的格子都无法到达,所以可以设置一个标志 hasObstacle,如果为1 ,表示在此之后的格子都无法到达。
解题过程
- 设置dp数组 : dp[i][j] 含义:到达 第 i - 1 行和j -1 列所有的不同路径的数量;
- 初始化dp数组:第一行和第一列只能通过向右走,和向下走到达,所以dp数组的第一行和第一列可以初始化,并且之后的dp数组的递推公式也需要用到第一行和第一列的数值来计算; 在赋值行的过程中,需要注意,一旦出现障碍物,右边的格子均无法到达,所以dp设为0;
- 求递推公式: dp[i][j] :
- 如果[i][j]处有障碍物,那么dp[i][j]直接设为0,即无法达到;
- 否则 因为机器人只能向下走或者向右走,那么到达[i][j]格子的路径数量可以由到达上一个格子的路径数量加上到达左边格子的路径数量的和推出来;(其实不用考虑上一个格子或者左边的格子的dp是否为0,如果为0,那么相加也为0,刚好符合题意
复杂度
- 时间复杂度: O(m + n)
- 空间复杂度: O(m*n)
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize) { int row = obstacleGridSize; int col = *obstacleGridColSize; if(obstacleGrid[0][0] == 1 || obstacleGrid[row - 1][col - 1] == 1){ return 0; } int** dp = (int**)malloc(sizeof(int*) * row); for(int i = 0;i < row; i ++){ dp[i] = (int*)malloc(sizeof(int) * col); memset(dp[i], 0 , sizeof(int) * col); } int hasObstacle = 0; for(int i = 0; i < row; i ++){ if(obstacleGrid[i][0] == 1){ hasObstacle = 1; } dp[i][0] = hasObstacle== 1 ? 0: 1; } hasObstacle = 0; for(int j = 0; j < col; j ++){ if(obstacleGrid[0][j] == 1){ hasObstacle = 1; } dp[0][j] = hasObstacle ==1 ? 0: 1; } for(int r = 1; r < row; r ++){ for(int c = 1; c < col; c ++){ if(obstacleGrid[r][c] == 1){ dp[r][c] = 0; }else{ dp[r][c] = dp[r][c - 1] + dp[r - 1][c]; } } } return dp[row - 1][col - 1]; } 作者:睡个好觉 链接:https://leetcode.cn/problems/unique-paths-ii/solutions/3624561/dong-tai-gui-hua-you-zhang-ai-wu-de-bu-t-siqu/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。