class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
return tabOpt(obstacleGrid);
}
int recur(int i, int j, int[][] ar, int[][] dp){
if(i==0 && j==0) return dp[i][j] = ((ar[i][j] == 1) ? 0:1);
if(i<0 || j<0) return 0;
if(ar[i][j]==1) return 0;
if(dp[i][j] != -1) return dp[i][j];
int up = recur(i-1,j,ar,dp);
int left = recur(i,j-1,ar,dp);
return dp[i][j] = up+left;
}
int tab(int[][] ar){
int r=ar.length, c=ar[0].length;
int[][] dp = new int[r][c];
dp[0][0] = (ar[0][0] == 1) ? 0:1;
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
if(i==0 && j==0) continue;
if(ar[i][j] == 1) dp[i][j]=0;
else{
int up = (i-1>=0) ? dp[i-1][j]:0;
int left = (j-1>=0) ?dp[i][j-1]:0;
dp[i][j] = up+left;
}
}
}
return dp[r-1][c-1];
}
int tabOpt(int[][] ar){
int r=ar.length, c=ar[0].length;
int[] prev = new int[c];
for(int i=0;i<r;i++){
int cur[] = new int[c];
for(int j=0;j<c;j++){
if(i==0 && j==0) {
cur[j] = (ar[0][0] == 1) ? 0:1;
continue;
}
if(ar[i][j] == 1) cur[j]=0;
else{
int up = (i-1>=0) ? prev[j]:0;
int left = (j-1>=0) ?cur[j-1]:0;
cur[j] = up+left;
}
}
prev = cur;
}
return prev[c-1];
}
}