和前一题一样的思路,但是因为障碍物的存在稍微有点不一样
在对最后一行赋值时,从最右往左扫描:在找到第一个障碍物的右侧都赋值1,左侧和障碍物处赋值0
在对最后一列赋值时,从最下往上扫描:在找到第一个障碍物的下侧都赋值1,上侧和障碍物处赋值0
然后 格子所在的值为 右侧 值 加下侧的值
最终返回matrix【0】【0】;
// 测试过了, 不考虑单独 一行一列的情况,oJ也能AC,估计OJ上没有一行或一列的test case
#include<vector>
#include<iostream>
using namespace std;
class Solution {
public:
// my fault: 在给最后一行和最后一列赋值时,没考虑到1所在的位置右侧和下侧是可以通行的。
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
if(m == 0){
return 0;
}
int n = obstacleGrid[0].size();
if(n == 0){
return 0;
}
if(m == 1 || n ==1){
bool flag = false;
int i=0;
if(m ==1){
// 只有一行的时候, 中间有障碍物
while(i<n){
if(obstacleGrid[0][i] == 1){
flag = true;
break;
}
++i;
}
}else{
// 只有一列的时候, 中间有障碍物
while(i < m){
if(obstacleGrid[i][0] == 1){
flag = true;
break;
}
++i;
}
}
if(flag){
return 0;
}
return 1;
}
// 多行多列的情况
vector<vector<long> > matrix(m);
for(int i=0;i<m;++i){
matrix[i].resize(n);
}
// 最后一行中是否有障碍物
int row=-1;
for(int i=n-1;i>=0;--i){
if(obstacleGrid[m-1][i] == 1){
row = i;
break;
}
}
// 最后一列中是否有障碍物
int col=-1;
for(int i=m-1;i>=0;--i){
if(obstacleGrid[i][n-1] == 1){
col = i;
break;
}
}
// 根据条件给最后一行 和 最后一列 赋值
// row
for(int i=0;i<n;++i){
matrix[m-1][i] = i<=row? 0 : 1;
}
// col
for(int i=0;i<m;++i){
matrix[i][n-1] = i<=col? 0 : 1;
}
for(int i=m-2;i>=0;--i){
for(int j=n-2;j>=0;--j){
if(obstacleGrid[i][j] == 1){
matrix[i][j] = 0;
}else{
matrix[i][j] = matrix[i][j+1] + matrix[i+1][j];
}
}
}
return matrix[0][0];
}
};
int main(){
Solution s;
vector<vector<int> > m({
{0,0,0},
{0,1,0},
{0,0,0}});
cout << s.uniquePathsWithObstacles(m);
return 0;
}