题意:
给出一个带有障碍物的棋盘,每次行动向下或向右移动一格,求从左上角到右下角有几种方案。
思路:
简单dp题,假设dp[i][j]表示第i行第j列的方案数,那么状态转移方程就为 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 。
注意下边界条件就好了,而且对于障碍物,直接把dp清零即可。
可以发现这个dp只和当前行和上一行有关,进而做空间优化,用一维数组即可,两维滚动数组也行(好想一点)。
代码:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>> &obstacleGrid) {
int n = obstacleGrid.size();
int m = obstacleGrid[0].size();
if (obstacleGrid[0][0] || obstacleGrid[n - 1][m - 1]) {
return 0;
}
int *dp = new int[m];
memset(dp, 0, sizeof(int) * m);
dp[0] = 1;
for (int i = 1; i < m; ++i) {
if (obstacleGrid[0][i]) {
break;
}
dp[i] = 1;
}
for (int i = 1; i < n; ++i) {
if (obstacleGrid[i][0]) {
dp[0] = 0;
}
for (int j = 1; j < m; ++j) {
if (obstacleGrid[i][j]) {
dp[j] = 0;
continue;
}
dp[j] += dp[j - 1];
// printf("i %d j %d dp %d\n", i, j, dp[j]);
}
}
return dp[m - 1];
}
};