Given a grid of size m * n, let us assume you are starting at (1, 1) and your goal is to reach (m, n). At any instance, if you are on (x, y), you can either go to (x, y + 1) or (x + 1, y).
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space are marked as 1 and 0 respectively in the grid.
Examples:Â Â
Input: [[0, 0, 0],
[0, 1, 0],
[0, 0, 0]]
Output : 2
There is only one obstacle in the middle.
Method 1: Recursion
We have discussed the problem to count the number of unique paths in a Grid when no obstacle was present in the grid. But here the situation is quite different. While moving through the grid, we can get some obstacles that we can not jump and the way to reach the bottom right corner is blocked.Â
C++
// C++ code to find number of unique paths // in a Matrix#include<bits/stdc++.h>using namespace std;Â
int UniquePathHelper(int i, int j, int r, int c, vector<vector<int>>& A){    // boundary condition or constraints    if(i == r || j == c){      return 0 ;    }Â
    if(A[i][j] == 1){      return 0 ;    }         // base case    if(i == r-1 && j == c-1){      return 1 ;    }Â
    return UniquePathHelper(i+1, j, r, c, A) +             UniquePathHelper(i, j+1, r, c, A) ;}Â
Â
int uniquePathsWithObstacles(vector<vector<int>>& A) {Â Â Â Â Â Â Â Â Â int r = A.size(), c = A[0].size(); Â
         return UniquePathHelper(0, 0, r, c, A) ;}Â
// Driver codeint main(){   vector<vector<int>> A = { { 0, 0, 0 },                             { 0, 1, 0 },                             { 0, 0, 0 } };                                 cout << uniquePathsWithObstacles(A) << " \n";                                               } |
Java
// Java code to find number of unique paths // in a Matriximport java.io.*;Â
class GFG {Â
  static int UniquePathHelper(int i, int j, int r, int c,                              int[][] A)  {    // boundary condition or constraints    if (i == r || j == c) {      return 0;    }Â
    if (A[i][j] == 1) {      return 0;    }Â
    // base case    if (i == r - 1 && j == c - 1) {      return 1;    }Â
    return UniquePathHelper(i + 1, j, r, c, A)      + UniquePathHelper(i, j + 1, r, c, A);  }Â
  static int uniquePathsWithObstacles(int[][] A)  {Â
    int r = A.length, c = A[0].length;Â
    return UniquePathHelper(0, 0, r, c, A);  }Â
  // Driver Code  public static void main(String[] args)  {    int[][] A      = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };Â
    System.out.print(uniquePathsWithObstacles(A));  }}Â
// This code is contributed by nipun_aggarwal |
Python3
# Python code to find number of unique paths # in a Matrixdef UniquePathHelper(i, j, r, c, A):       # boundary condition or constraints    if(i == r or j == c):      return 0         if(A[i][j] == 1):      return 0         # base case    if(i == r-1 and j == c-1):      return 1Â
    return UniquePathHelper(i+1, j, r, c, A) + UniquePathHelper(i, j+1, r, c, A) Â
def uniquePathsWithObstacles(A): Â Â Â Â r,c = len(A),len(A[0])Â Â Â Â Â Â Â Â Â return UniquePathHelper(0, 0, r, c, A)Â
# Driver codeA = [ [ 0, 0, 0 ],      [ 0, 1, 0 ],      [ 0, 0, 0 ] ]                              print(uniquePathsWithObstacles(A))                                          Â
# This code is contributed by shinjanpatra |
C#
// C# code to find number of unique paths// in a Matrixusing System;class Program {Â
  // Driver code  static void Main(string[] args)  {    int[, ] A = new int[3, 3] { { 0, 0, 0 },                               { 0, 1, 0 },                               { 0, 0, 0 } };    Console.WriteLine(uniquePathsWithObstacles(A));  }Â
  static int uniquePathsWithObstacles(int[, ] A)  {    int r = A.GetLength(0);    int c = A.GetLength(1);    return UniquePathHelper(0, 0, r, c, A);  }Â
  static int UniquePathHelper(int i, int j, int r, int c,                              int[, ] A)  {    // boundary condition or constraints    if (i == r || j == c) {      return 0;    }Â
    if (A[i, j] == 1) {      return 0;    }Â
    // base case    if (i == r - 1 && j == c - 1) {      return 1;    }Â
    return UniquePathHelper(i + 1, j, r, c, A)      + UniquePathHelper(i, j + 1, r, c, A);  }}Â
// This code is contributed by Tapesh(tapeshdua420) |
Javascript
<script>Â
// JavaScript code to find number of unique paths // in a Matrixfunction UniquePathHelper(i, j, r, c, A){       // boundary condition or constraints    if(i == r || j == c)      return 0          if(A[i][j] == 1)      return 0          // base case    if(i == r-1 && j == c-1)      return 1 Â
    return UniquePathHelper(i+1, j, r, c, A) + UniquePathHelper(i, j+1, r, c, A) }Â
function uniquePathsWithObstacles(A){     let r = A.length, c = A[0].length         return UniquePathHelper(0, 0, r, c, A)}Â
// Driver codelet A = [ [ 0, 0, 0 ],      [ 0, 1, 0 ],      [ 0, 0, 0 ] ]                              document.write(uniquePathsWithObstacles(A))                                          Â
// This code is contributed by shinjanpatra Â
</script> |
2
Time Complexity: O(2m*n)
Auxiliary Space: O(m+n) , because worst path will be when we iterate along corner cells, Recursion will not have all the paths so Space can’t be O(n*m) it should be O(n+m)
Method 2: Using DP
1) Top-Down
The most efficient solution to this problem can be achieved using dynamic programming. Like every dynamic problem concept, we will not recompute the subproblems. A temporary 2D matrix will be constructed and value will be stored using the top-down approach.Â
C++
// C++ code to find number of unique paths// in a Matrix#include <bits/stdc++.h>using namespace std;Â
int UniquePathHelper(int i, int j, int r, int c,                     vector<vector<int> >& A,                     vector<vector<int> >& paths){    // boundary condition or constraints    if (i == r || j == c) {        return 0;    }Â
    if (A[i][j] == 1) {        return 0;    }Â
    // base case    if (i == r - 1 && j == c - 1) {        return 1;    }Â
    if (paths[i][j] != -1) {        return paths[i][j];    }Â
    return paths[i][j]           = UniquePathHelper(i + 1, j, r, c, A, paths)             + UniquePathHelper(i, j + 1, r, c, A, paths);}Â
int uniquePathsWithObstacles(vector<vector<int> >& A){Â
    int r = A.size(), c = A[0].size();Â
    // create a 2D-matrix and initializing    // with value 0Â
    vector<vector<int> > paths(r, vector<int>(c, -1));Â
    return UniquePathHelper(0, 0, r, c, A, paths);}Â
// Driver codeint main(){Â Â Â Â vector<vector<int> > AÂ Â Â Â Â Â Â Â = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };Â
    cout << uniquePathsWithObstacles(A) << " \n";} |
Java
// Java code to find number of unique paths// in a Matriximport java.util.*;Â
public class Main {Â Â Â Â public static void main(String[] args)Â Â Â Â {Â Â Â Â Â Â Â Â int[][] AÂ Â Â Â Â Â Â Â Â Â Â Â = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };Â Â Â Â Â Â Â Â System.out.println(uniquePathsWithObstacles(A));Â Â Â Â }Â
    public static int uniquePathsWithObstacles(int[][] A)    {        int r = A.length;        int c = A[0].length;        // create a 2D-matrix and initializing        // with value 0        int[][] paths = new int[r];Â
        for (int i = 0; i < r; i++) {            Arrays.fill(paths[i], -1);        }Â
        return UniquePathHelper(0, 0, r, c, A, paths);    }Â
    public static int UniquePathHelper(int i, int j, int r,                                       int c, int[][] A,                                       int[][] paths)    {        // boundary condition or constraints        if (i == r || j == c) {            return 0;        }        else if (A[i][j] == 1) {            return 0;        }        // base case        else if (i == r - 1 && j == c - 1) {            return 1;        }        else if (paths[i][j] != -1) {Â
            return paths[i][j];        }        else {            return paths[i][j]                = UniquePathHelper(i + 1, j, r, c, A, paths)                  + UniquePathHelper(i, j + 1, r, c, A,                                     paths);        }    }}Â
// This code is contributed by Tapesh(tapeshdua420) |
Python3
# Python code to find number of unique paths# in a MatrixÂ
Â
def UniquePathHelper(i, j, r, c, A, paths):    # boundary condition or constraints    if (i == r or j == c):        return 0Â
    if (A[i][j] == 1):        return 0Â
    # base case    if (i == r - 1 and j == c - 1):        return 1Â
    if (paths[i][j] != -1):        return paths[i][j]Â
    paths[i][j] = UniquePathHelper(        i + 1, j, r, c, A, paths) + UniquePathHelper(i, j + 1, r, c, A, paths)    return paths[i][j]Â
Â
def uniquePathsWithObstacles(A):Â
    r, c = len(A), len(A[0])Â
    # create a 2D-matrix and initializing    # with value 0Â
    paths = [[-1 for i in range(c)]for j in range(r)]Â
    return UniquePathHelper(0, 0, r, c, A, paths)Â
# Driver codeÂ
Â
A = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]Â
print(uniquePathsWithObstacles(A))Â
# code is contributed by shinjanpatra |
C#
// C# code to find number of unique paths// in a Matrixusing System;Â
class Program {Â
    // Driver code    static void Main(string[] args)    {        int[, ] A = new int[3, 3] { { 0, 0, 0 },                                    { 0, 1, 0 },                                    { 0, 0, 0 } };        Console.WriteLine(uniquePathsWithObstacles(A));    }Â
    static int uniquePathsWithObstacles(int[, ] A)    {        int r = A.GetLength(0);        int c = A.GetLength(1);Â
        // create a 2D-matrix and initializing        // with value -1        int[, ] paths = new int[r, c];        for (int i = 0; i < r; i++) {            for (int j = 0; j < c; j++) {                paths[i, j] = -1;            }        }Â
        return UniquePathHelper(0, 0, r, c, A, paths);    }Â
    static int UniquePathHelper(int i, int j, int r, int c,                                int[, ] A, int[, ] paths)    {        // boundary condition or constraints        if (i == r || j == c) {            return 0;        }Â
        if (A[i, j] == 1) {            return 0;        }Â
        // base case        if (i == r - 1 && j == c - 1) {            return 1;        }Â
        if (paths[i, j] != -1) {            return paths[i, j];        }Â
        return paths[i][j]            = UniquePathHelper(i + 1, j, r, c, A, paths)              + UniquePathHelper(i, j + 1, r, c, A, paths);    }}Â
// This code is contributed by Tapesh(tapeshdua420) |
Javascript
<script>Â
// JavaScript code to find number of unique paths// in a Matrixfunction UniquePathHelper(i, j, r, c, A, paths){Â
    // boundary condition or constraints    if (i == r || j == c) {        return 0;    }Â
    if (paths[i][j] == 1) {        return 0;    }Â
    // base case    if (i == r - 1 && j == c - 1) {        return 1;    }Â
    if (paths[i][j] != -1) {        return paths[i][j];    }Â
    return paths[i][j]           = UniquePathHelper(i + 1, j, r, c, A, paths)           + UniquePathHelper(i, j + 1, r, c, A, paths);}Â
function uniquePathsWithObstacles(A){Â
    let r = A.length, c = A[0].length;Â
    // create a 2D-matrix and initializing    // with value 0    let paths = new Array(c);    for(let i = 0; i < r; i++){        paths[i] = new Array(c).fill(-1);    }Â
    return UniquePathHelper(0, 0, r, c, A, paths);}Â
// Driver codelet AÂ = [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 0 ] ]document.write(uniquePathsWithObstacles(A))Â
// This code is contributed by shinjanpatraÂ
</script> |
2
Time Complexity: O(m*n)Â
Auxiliary Space: O(m*n)
2) Bottom-Up
A temporary 2D matrix will be constructed and value will be stored using the bottom-up approach.Â
Approach:
- Create a 2D matrix of the same size as the given matrix to store the results.
- Traverse through the created array row-wise and start filling the values in it.
- If an obstacle is found, set the value to 0.
- For the first row and column, set the value to 1 if an obstacle is not found.
- Set the sum of the right and the upper values if an obstacle is not present at that corresponding position in the given matrix
- Return the last value of the created 2d matrix
Below is the implementation of the above approach:
C++
// C++ code to find number of unique paths // in a Matrix#include<bits/stdc++.h>using namespace std;Â
int uniquePathsWithObstacles(vector<vector<int>>& A) {         int r = A.size(), c = A[0].size();          // create a 2D-matrix and initializing    // with value 0    vector<vector<int>> paths(r, vector<int>(c, 0));         // Initializing the left corner if    // no obstacle there    if (A[0][0] == 0)        paths[0][0] = 1;             // Initializing first column of    // the 2D matrix    for(int i = 1; i < r; i++)    {        // If not obstacle        if (A[i][0] == 0)            paths[i][0] = paths[i-1][0];    }          // Initializing first row of the 2D matrix    for(int j = 1; j < c; j++)    {                 // If not obstacle        if (A[0][j] == 0)            paths[0][j] = paths[0][j - 1];    }            for(int i = 1; i < r; i++)    {        for(int j = 1; j < c; j++)        {                         // If current cell is not obstacle             if (A[i][j] == 0)                paths[i][j] = paths[i - 1][j] +                              paths[i][j - 1];         }     }         // Returning the corner value     // of the matrix    return paths[r - 1];}Â
// Driver codeint main(){   vector<vector<int>> A = { { 0, 0, 0 },                             { 0, 1, 0 },                             { 0, 0, 0 } };                                 cout << uniquePathsWithObstacles(A) << " \n";                                               }Â
// This code is contributed by ajaykr00kj |
Java
// Java code to find number of unique paths // in a Matrixpublic class Main{Â Â static int uniquePathsWithObstacles(int[][] A) Â Â {Â
    int r = 3, c = 3; Â
    // create a 2D-matrix and initializing    // with value 0    int[][] paths = new int[r];    for(int i = 0; i < r; i++)    {      for(int j = 0; j < c; j++)      {        paths[i][j] = 0;      }    }Â
    // Initializing the left corner if    // no obstacle there    if (A[0][0] == 0)      paths[0][0] = 1;Â
    // Initializing first column of    // the 2D matrix    for(int i = 1; i < r; i++)    {      // If not obstacle      if (A[i][0] == 0)        paths[i][0] = paths[i - 1][0];    } Â
    // Initializing first row of the 2D matrix    for(int j = 1; j < c; j++)    {Â
      // If not obstacle      if (A[0][j] == 0)        paths[0][j] = paths[0][j - 1];    }  Â
    for(int i = 1; i < r; i++)    {      for(int j = 1; j < c; j++)      {Â
        // If current cell is not obstacle         if (A[i][j] == 0)          paths[i][j] = paths[i - 1][j] +          paths[i][j - 1];       }     }Â
    // Returning the corner value     // of the matrix    return paths[r - 1];  }Â
  // Driver code  public static void main(String[] args) {    int[][] A = { { 0, 0, 0 },                 { 0, 1, 0 },                 { 0, 0, 0 } };Â
    System.out.print(uniquePathsWithObstacles(A));  }}Â
// This code is contributed by divyeshrabadiya07. |
Python
# Python code to find number of unique paths in a # matrix with obstacles.Â
def uniquePathsWithObstacles(A):Â
    # create a 2D-matrix and initializing with value 0    paths = [[0]*len(A[0]) for i in A]         # initializing the left corner if no obstacle there    if A[0][0] == 0:        paths[0][0] = 1         # initializing first column of the 2D matrix    for i in range(1, len(A)):                 # If not obstacle        if A[i][0] == 0:            paths[i][0] = paths[i-1][0]                 # initializing first row of the 2D matrix    for j in range(1, len(A[0])):                 # If not obstacle        if A[0][j] == 0:            paths[0][j] = paths[0][j-1]                 for i in range(1, len(A)):        for j in range(1, len(A[0])):Â
            # If current cell is not obstacle            if A[i][j] == 0:                paths[i][j] = paths[i-1][j] + paths[i][j-1]Â
    # returning the corner value of the matrix    return paths[-1][-1]Â
Â
# Driver CodeA = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]print(uniquePathsWithObstacles(A)) |
C#
// C# code to find number of unique paths // in a Matrixusing System;class GFG {Â
  static int uniquePathsWithObstacles(int[,] A)   {Â
    int r = 3, c = 3; Â
    // create a 2D-matrix and initializing    // with value 0    int[,] paths = new int[r,c];    for(int i = 0; i < r; i++)    {      for(int j = 0; j < c; j++)      {        paths[i, j] = 0;      }    }Â
    // Initializing the left corner if    // no obstacle there    if (A[0, 0] == 0)      paths[0, 0] = 1;Â
    // Initializing first column of    // the 2D matrix    for(int i = 1; i < r; i++)    {      // If not obstacle      if (A[i, 0] == 0)        paths[i, 0] = paths[i - 1, 0];    } Â
    // Initializing first row of the 2D matrix    for(int j = 1; j < c; j++)    {Â
      // If not obstacle      if (A[0, j] == 0)        paths[0, j] = paths[0, j - 1];    }  Â
    for(int i = 1; i < r; i++)    {      for(int j = 1; j < c; j++)      {Â
        // If current cell is not obstacle         if (A[i, j] == 0)          paths[i, j] = paths[i - 1, j] +          paths[i, j - 1];       }     }Â
    // Returning the corner value     // of the matrix    return paths[r - 1, c - 1];  }Â
  // Driver code  static void Main() {    int[,] A = { { 0, 0, 0 },                { 0, 1, 0 },                { 0, 0, 0 } };Â
    Console.WriteLine(uniquePathsWithObstacles(A));  }}Â
// This code is contributed by divyesh072019. |
Javascript
<script>    // Javascript code to find number of unique paths    // in a Matrix         function uniquePathsWithObstacles(A)    {Â
      let r = 3, c = 3;Â
      // create a 2D-matrix and initializing      // with value 0      let paths = new Array(r);      for(let i = 0; i < r; i++)      {          paths[i] = new Array(c);        for(let j = 0; j < c; j++)        {          paths[i][j] = 0;        }      }Â
      // Initializing the left corner if      // no obstacle there      if (A[0][0] == 0)        paths[0][0] = 1;Â
      // Initializing first column of      // the 2D matrix      for(let i = 1; i < r; i++)      {        // If not obstacle        if (A[i][0] == 0)          paths[i][0] = paths[i - 1][0];      }Â
      // Initializing first row of the 2D matrix      for(let j = 1; j < c; j++)      {Â
        // If not obstacle        if (A[0][j] == 0)          paths[0][j] = paths[0][j - 1];      } Â
      for(let i = 1; i < r; i++)      {        for(let j = 1; j < c; j++)        {Â
          // If current cell is not obstacle          if (A[i][j] == 0)            paths[i][j] = paths[i - 1][j] +            paths[i][j - 1];        }       }Â
      // Returning the corner value      // of the matrix      return paths[r - 1];    }           let A = [ [ 0, 0, 0 ],             [ 0, 1, 0 ],             [ 0, 0, 0 ] ];      document.write(uniquePathsWithObstacles(A));         // This code is contributed by suresh07.</script> |
2
Time Complexity: O(m*n)Â
Auxiliary Space: O(m*n)
Method 3: Space Optimization of DP solution.
In this method, we will use the given ‘A’ 2D matrix to store the previous answer using the bottom-up approach.
Approach
- Start traversing through the given ‘A’ 2D matrix row-wise and fill the values in it.
- For the first row and the first column set the value to 1 if an obstacle is not found.
- For the first row and first column, if an obstacle is found then start filling 0 till the last index in that particular row or column.
- Now start traversing from the second row and column ( eg: A[ 1 ][ 1 ]).
- If an obstacle is found, set 0 at particular Grid ( eg: A[ i ][ j ] ), otherwise set sum of upper and left values at A[ i ][ j ].
- Return the last value of the 2D matrix.
Below is the implementation of the above approach.Â
C++
// CPP program for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
int uniquePathsWithObstacles(vector<vector<int> >& A){Â
    int r = A.size();    int c = A[0].size();Â
    // If obstacle is at starting position    if (A[0][0])        return 0;Â
    // Initializing starting position    A[0][0] = 1;Â
    // first row all are '1' until obstacle    for (int j = 1; j < c; j++) {Â
        if (A[0][j] == 0) {            A[0][j] = A[0][j - 1];        }        else {            // No ways to reach at this index            A[0][j] = 0;        }    }Â
    // first column all are '1' until obstacle    for (int i = 1; i < r; i++) {Â
        if (A[i][0] == 0) {            A[i][0] = A[i - 1][0];        }        else {            // No ways to reach at this index            A[i][0] = 0;        }    }Â
    for (int i = 1; i < r; i++) {Â
        for (int j = 1; j < c; j++) {            // If current cell has no obstacle            if (A[i][j] == 0) {Â
                A[i][j] = A[i - 1][j] + A[i][j - 1];            }            else {                // No ways to reach at this index                A[i][j] = 0;            }        }    }Â
    // returning the bottom right    // corner of Grid    return A[r - 1];}Â
// Driver CodeÂ
int main(){Â
    vector<vector<int> > A        = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };Â
    cout << uniquePathsWithObstacles(A) << "\n";Â
    return 0;}// This code is contributed by hemantraj712 |
Java
// Java program for the above approachimport java.io.*;class GFG {Â
    static int uniquePathsWithObstacles(int[][] A)    {Â
        int r = A.length;        int c = A[0].length;Â
        // If obstacle is at starting position        if (A[0][0] != 0)            return 0;Â
        // Initializing starting position        A[0][0] = 1;Â
        // first row all are '1' until obstacle        for (int j = 1; j < c; j++) {Â
            if (A[0][j] == 0) {                A[0][j] = A[0][j - 1];            }            else {                // No ways to reach at this index                A[0][j] = 0;            }        }Â
        // first column all are '1' until obstacle        for (int i = 1; i < r; i++) {Â
            if (A[i][0] == 0) {                A[i][0] = A[i - 1][0];            }            else {                // No ways to reach at this index                A[i][0] = 0;            }        }Â
        for (int i = 1; i < r; i++) {Â
            for (int j = 1; j < c; j++) {Â
                // If current cell has no obstacle                if (A[i][j] == 0) {Â
                    A[i][j] = A[i - 1][j] + A[i][j - 1];                }                else {                    // No ways to reach at this index                    A[i][j] = 0;                }            }        }Â
        // returning the bottom right        // corner of Grid        return A[r - 1];    }Â
    // Driver code    public static void main(String[] args)    {        int[][] A            = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };Â
        System.out.print(uniquePathsWithObstacles(A));    }}Â
// This code is contributed by rajsanghavi9. |
Python3
# Python program for the above approachÂ
Â
def uniquePathsWithObstacles(A):Â
    r = len(A)    c = len(A[0])Â
    # If obstacle is at starting position    if (A[0][0]):        return 0Â
    # Initializing starting position    A[0][0] = 1Â
    # first row all are '1' until obstacle    for j in range(1,c):Â
        if (A[0][j] == 0):            A[0][j] = A[0][j - 1]        else:            # No ways to reach at this index            A[0][j] = 0Â
    # first column all are '1' until obstacle    for i in range(1,r):Â
        if (A[i][0] == 0):            A[i][0] = A[i - 1][0]        else:            # No ways to reach at this index            A[i][0] = 0Â
    for i in range(1,r):Â
        for j in range(1,c):            # If current cell has no obstacle            if (A[i][j] == 0):Â
                A[i][j] = A[i - 1][j] + A[i][j - 1]            else:                # No ways to reach at this index                A[i][j] = 0Â
    # returning the bottom right    # corner of Grid    return A[r - 1]Â
# Driver CodeÂ
A = [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 0 ] ]Â
print(uniquePathsWithObstacles(A))Â
# This code is contributed by shinjanpatra |
C#
// C# program for the above approachusing System;using System.Collections.Generic;Â
class Program {Â Â static int uniquePathsWithObstacles(int[, ] A)Â Â {Â Â Â Â int r = A.GetLength(0);Â Â Â Â int c = A.GetLength(1);Â
    // If obstacle is at starting position    if (A[0, 0] != 0)      return 0;Â
    // Initializing starting position    A[0, 0] = 1;    for (int j = 1; j < c; j++) {      if (A[0, j] == 0) {        A[0, j] = A[0, j - 1];      }      else {        A[0, j] = 0;      }    }Â
    // first row all are '1' until obstacle    for (int i = 1; i < r; i++) {      if (A[i, 0] == 0) {        A[i, 0] = A[i - 1, 0];      }      else {        // No ways to reach at this index        A[i, 0] = 0;      }    }Â
    for (int i = 1; i < r; i++) {      for (int j = 1; j < c; j++) {        // If current cell has no obstacle        if (A[i, j] == 0) {          A[i, j] = A[i - 1, j] + A[i, j - 1];        }        else {          // No ways to reach at this index          A[i, j] = 0;        }      }    }    // returning the bottom right    // corner of Grid    return A[r - 1, c - 1];  }     // Driver code  public static void Main(String[] args)  {Â
    int[, ] A = new int[3, 3] { { 0, 0, 0 },                               { 0, 1, 0 },                               { 0, 0, 0 } };Â
    Console.WriteLine(uniquePathsWithObstacles(A));  }}Â
// This code is contributed by Tapesh (tapeshdua420) |
Javascript
<script>Â
// JavaScript program for the above approachfunction uniquePathsWithObstacles(A){Â
    let r = A.length    let c = A[0].lengthÂ
    // If obstacle is at starting position    if (A[0][0])        return 0Â
    // Initializing starting position    A[0][0] = 1Â
    // first row all are '1' until obstacle    for(let j = 1; j < c; j++)    {        if (A[0][j] == 0)            A[0][j] = A[0][j - 1]        else            // No ways to reach at this index            A[0][j] = 0    }Â
    // first column all are '1' until obstacle    for(let i = 1; i < r; i++){Â
        if (A[i][0] == 0)            A[i][0] = A[i - 1][0]        else            // No ways to reach at this index            A[i][0] = 0    }Â
   for(let i = 1; i < r; i++){Â
      for(let j = 1; j < c; j++){            // If current cell has no obstacle            if (A[i][j] == 0)Â
                A[i][j] = A[i - 1][j] + A[i][j - 1]            else                // No ways to reach at this index                A[i][j] = 0      }   }Â
    // returning the bottom right    // corner of Grid    return A[r - 1]}Â
// Driver Codelet A = [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 0 ] ]document.write(uniquePathsWithObstacles(A),"</br>")Â
// This code is contributed by shinjanpatraÂ
</script> |
2
Time Complexity: O(m*n) Â
Auxiliary Space: O(1)
The 2D Dp Approach:
As Per Problem tell us that we can move in two ways  can either go to (x, y + 1) or (x + 1, y). So we just calculate all possible outcome in both ways and store in 2d dp vector and return the dp[0][0] i.e all possible ways that takes you from (0,0) to (n-1,m-1);
C++
#include <bits/stdc++.h>#define int long longusing namespace std;int n, m;int path(vector<vector<int> >& dp,         vector<vector<int> >& grid, int i, int j){    if (i < n && j < m && grid[i][j] == 1)        return 0;    if (i == n - 1 && j == m - 1)        return 1;    if (i >= n || j >= m)        return 0;    if (dp[i][j] != -1)        return dp[i][j];    int left = path(dp, grid, i + 1, j);    int right = path(dp, grid, i, j + 1);    return dp[i][j] = left + right;}int uniquePathsWithObstacles(vector<vector<int> >& grid){    n = grid.size();    m = grid[0].size();    if (n == 1 && m == 1 && grid[0][0] == 0)        return 1;    if (n == 1 && m == 1 && grid[0][0] == 1)        return 0;    vector<vector<int> > dp(n, vector<int>(m, -1));    // for(auto it:dp){    //    for(auto vt:it)cout<<vt<<" ";    //    cout<<endl;    // }    path(dp, grid, 0, 0);    // for(auto it:dp){    //    for(auto vt:it)cout<<vt<<" ";    //    cout<<endl;    // }    if (dp[0][0] == -1)        return 0;    return dp[0][0];}// Driver Codesigned main(){    vector<vector<int> > v{ { 0, 0, 0 },                            { 0, 1, 0 },                            { 0, 0, 0 } };    cout << uniquePathsWithObstacles(v) << " \n";    return 0;} |
Java
// Java code for the above approachimport java.util.*;Â
class Main {Â Â Â Â static int n, m;Â
    static int path(int[][] dp, int[][] grid, int i, int j)    {        if (i < n && j < m && grid[i][j] == 1)            return 0;        if (i == n - 1 && j == m - 1)            return 1;        if (i >= n || j >= m)            return 0;        if (dp[i][j] != -1)            return dp[i][j];        int left = path(dp, grid, i + 1, j);        int right = path(dp, grid, i, j + 1);        return dp[i][j] = left + right;    }Â
    static int uniquePathsWithObstacles(int[][] grid)    {        n = grid.length;        m = grid[0].length;        if (n == 1 && m == 1 && grid[0][0] == 0)            return 1;        if (n == 1 && m == 1 && grid[0][0] == 1)            return 0;        int[][] dp = new int[n][m];        for (int i = 0; i < n; i++) {            for (int j = 0; j < m; j++) {                dp[i][j] = -1;            }        }        path(dp, grid, 0, 0);        if (dp[0][0] == -1)            return 0;        return dp[0][0];    }Â
    public static void main(String[] args)    {        int[][] v            = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };        System.out.println(uniquePathsWithObstacles(v));    }}Â
// This code is contributed by pradeepkumarppk2003 |
Python3
# Python code for the above approachdef uniquePathsWithObstacles(grid):Â Â Â Â n = len(grid)Â Â Â Â m = len(grid[0])Â Â Â Â if n == 1 and m == 1 and grid[0][0] == 0:Â Â Â Â Â Â Â Â return 1Â Â Â Â if n == 1 and m == 1 and grid[0][0] == 1:Â Â Â Â Â Â Â Â return 0Â Â Â Â dp = [[-1 for j in range(m)] for i in range(n)]Â
    def path(dp, grid, i, j):        if i < n and j < m and grid[i][j] == 1:            return 0        if i == n - 1 and j == m - 1:            return 1        if i >= n or j >= m:            return 0        if dp[i][j] != -1:            return dp[i][j]        left = path(dp, grid, i + 1, j)        right = path(dp, grid, i, j + 1)        dp[i][j] = left + right        return dp[i][j]    path(dp, grid, 0, 0)    if dp[0][0] == -1:        return 0    return dp[0][0]Â
Â
# Driver Codegrid = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]print(uniquePathsWithObstacles(grid))Â
# This code is contributed by lokeshpotta20. |
Javascript
let n,m;function path(dp, grid, i, j){Â Â Â Â if(i<n && j<m && grid[i][j]==1)Â Â Â Â Â Â Â Â return 0;Â Â Â Â if(i==n-1 && j==m-1)Â Â Â Â Â Â Â Â return 1;Â Â Â Â if(i>=n || j>=m)Â Â Â Â Â Â Â Â return 0;Â Â Â Â if(dp[i][j]!=-1)Â Â Â Â Â Â Â Â return dp[i][j];Â Â Â Â let left=path(dp,grid,i+1,j);Â Â Â Â let right=path(dp,grid,i,j+1);Â Â Â Â return dp[i][j]=left+right;}function uniquePathsWithObstacles(grid) {Â Â Â Â n=grid.length;Â Â Â Â m=grid[0].length;Â Â Â Â if(n==1 && m==1 && grid[0][0]==0)Â Â Â Â Â Â Â Â return 1;Â Â Â Â if(n==1 && m==1 && grid[0][0]==1)Â Â Â Â Â Â Â Â return 0;Â Â Â Â let dp=new Array(n);Â Â Â Â for(let i=0; i<n; i++)Â Â Â Â Â Â Â Â dp[i]=new Array(m).fill(-1);Â Â Â Â //for(let i=0; i<dp.length; i++){Â Â Â Â Â Â Â // for(let j=0; j<dp[0].length; j++)Â Â Â Â Â Â Â Â Â Â //Â console.log(dp[i][j]);Â Â Â Â //Â Â Â Â cout<<endl;Â Â Â // }Â Â Â Â path(dp,grid,0,0);Â Â Â Â //for(let i=0; i<dp.length; i++){Â Â Â Â Â Â //Â for(let j=0; j<dp[0].length; j++)Â Â Â Â Â Â Â Â //Â Â Â console.log(dp[i][j]);Â Â Â Â //Â Â Â Â cout<<endl;Â Â Â Â //}Â Â Â Â if(dp[0][0]==-1)Â Â Â Â Â Â Â Â return 0;Â Â Â Â return dp[0][0];}// Driver Codelet v=[[ 0, 0, 0 ],[ 0, 1, 0 ],[ 0, 0, 0 ]];console.log(uniquePathsWithObstacles(v)); |
C#
using System;using System.Collections.Generic;Â
namespace UniquePathsWithObstacles {class Program {    static void Main(string[] args)    {        int[][] grid            = new int[][] { new int[] { 0, 0, 0 },                            new int[] { 0, 1, 0 },                            new int[] { 0, 0, 0 } };        Console.WriteLine(UniquePathsWithObstacles(grid));    }Â
    static int UniquePathsWithObstacles(int[][] grid)    {        int n = grid.Length;        int m = grid[0].Length;        if (n == 1 && m == 1 && grid[0][0] == 0)            return 1;        if (n == 1 && m == 1 && grid[0][0] == 1)            return 0;Â
        int[][] dp = new int[n][];        for (int i = 0; i < n; i++) {            dp[i] = new int[m];            for (int j = 0; j < m; j++) {                dp[i][j] = -1;            }        }Â
        int result = Path(dp, grid, 0, 0);        if (dp[0][0] == -1)            return 0;        return dp[0][0];    }Â
    static int Path(int[][] dp, int[][] grid, int i, int j)    {        int n = grid.Length;        int m = grid[0].Length;        if (i < n && j < m && grid[i][j] == 1)            return 0;        if (i == n - 1 && j == m - 1)            return 1;        if (i >= n || j >= m)            return 0;        if (dp[i][j] != -1)            return dp[i][j];        int left = Path(dp, grid, i + 1, j);        int right = Path(dp, grid, i, j + 1);        return dp[i][j] = left + right;    }}} |
2
Time Complexity: O(M*N),For traversing all possible ways.
Auxiliary Space: O(M*N),For storing in 2D Dp Vector.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
