Unique paths in a Grid with Obstacles

Last Updated : 10 Jun, 2026

Given a grid grid[][] of size n × m containing values 0 and 1 having the following meanings:

  • 0 represents an open cell through which movement is allowed.
  • 1 represents a blocked cell that cannot be traversed.

Starting from the top-left cell (0, 0), find the total number of distinct paths to reach the bottom-right cell (n - 1, m - 1). From any cell, movement is allowed only in the right and down directions, and a path is valid only if it passes through open cells.

Note: It is guaranteed that the answer fits within a 32-bit integer.

Examples:  

Input: grid[][] = {{0, 0, 0},{0, 1, 0},{0, 0, 0}}
Output: 2
Explanation: There are two distinct paths from (0, 0) to (2, 2) while avoiding the blocked cell.

sss

Input: grid[][] = {{1, 0, 1}}
Output: 0
Explanation: There is no possible path to reach the end.

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(2^(n*m)) Time and O(n+m) Space

The idea is to start from the top-left cell and try all possible ways to reach the bottom-right cell. From any cell, we can move either down or right. We recursively explore both choices and count the number of valid paths. If we reach a blocked cell or go outside the grid, that path is discarded.

Base Cases:

  • If i == r or j == c: The current position is out of bounds, so there are no paths available. Return 0.
  • If grid[i][j] == 1: The current cell is an obstacle, so it cannot be used. Return 0.
  • If i == r-1 and j == c-1: The function has reached the destination, so there is exactly one path. Return 1.

The recurrence relation will be:

  • uniPathRec(i, j, r, c, grid) = uniPathRec(i+1, j, r, c, grid) + uniPathRec(i, j+1, r, c, grid)
C++
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;

//Driver Code Ends

// Helper function to find unique paths recursively
int uniPathRec(int i, int j, vector<vector<int>>& grid) {
    int r = grid.size(), c = grid[0].size();

	// If out of bounds, return 0
	if(i == r || j == c) {
		return 0;
	}

	// If cell is an obstacle, return 0
	if(grid[i][j] == 1) {
		return 0;
	}

	// If reached the bottom-right cell, return 1
	if(i == r-1 && j == c-1) {
		return 1;
	}

	// Recur for the cell below and the cell to the right
	return uniPathRec(i+1, j, grid) +
	       uniPathRec(i, j+1, grid);
}

// Function to find unique paths with obstacles
int uniquePaths(vector<vector<int>>& grid) {
	return uniPathRec(0, 0, grid);
}

//Driver Code Starts

int main() {

	vector<vector<int>> grid = { { 0, 0, 0 },{ 0, 1, 0 },{ 0, 0, 0 }
	};

	cout << uniquePaths(grid);
}

//Driver Code Ends
Java
//Driver Code Starts
public class GFG {

//Driver Code Ends

    // Helper function to find unique paths recursively
    static int uniPathRec(int i, int j, int[][] grid) {
        int r = grid.length, c = grid[0].length;

        // If out of bounds, return 0
        if (i == r || j == c) {
            return 0;
        }

        // If cell is an obstacle, return 0
        if (grid[i][j] == 1) {
            return 0;
        }

        // If reached the bottom-right cell, return 1
        if (i == r - 1 && j == c - 1) {
            return 1;
        }

        // Recur for the cell below and the cell to the right
        return uniPathRec(i + 1, j, grid) +
               uniPathRec(i, j + 1, grid);
    }

    // Function to find unique paths with obstacles
    static int uniquePaths(int[][] grid) {
        return uniPathRec(0, 0, grid);
    }

//Driver Code Starts

    public static void main(String[] args) {

        int[][] grid = {
            {0, 0, 0},
            {0, 1, 0},
            {0, 0, 0}
        };

        System.out.println(uniquePaths(grid));
    }
}

//Driver Code Ends
Python
# Helper function to find unique paths recursively
def uniPathRec(i, j, grid):
    r, c = len(grid), len(grid[0])

    # If out of bounds, return 0
    if i == r or j == c:
        return 0

    # If cell is an obstacle, return 0
    if grid[i][j] == 1:
        return 0

    # If reached the bottom-right cell, return 1
    if i == r-1 and j == c-1:
        return 1

    # Recur for the cell below and the cell to the right
    return uniPathRec(i+1, j, grid) + \
           uniPathRec(i, j+1, grid)

# Function to find unique paths with obstacles
def uniquePaths(grid):
    return uniPathRec(0, 0, grid)


#Driver Code Starts

if __name__ == "__main__":
    grid = [
        [0, 0, 0],
        [0, 1, 0],
        [0, 0, 0]
    ]
    
    print(uniquePaths(grid))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG
{
//Driver Code Ends

    // Helper function to find unique paths recursively
    static int uniPathRec(int i, int j, int[,] grid)
    {
        int r = grid.GetLength(0);
        int c = grid.GetLength(1);

        // If out of bounds, return 0
        if (i == r || j == c)
        {
            return 0;
        }

        // If cell is an obstacle, return 0
        if (grid[i, j] == 1)
        {
            return 0;
        }

        // If reached the bottom-right cell, return 1
        if (i == r - 1 && j == c - 1)
        {
            return 1;
        }

        // Recur for the cell below and the cell to the right
        return uniPathRec(i + 1, j, grid) +
               uniPathRec(i, j + 1, grid);
    }

    // Function to find unique paths with obstacles
    static int uniquePaths(int[,] grid)
    {
        return uniPathRec(0, 0, grid);
    }

//Driver Code Starts

    static void Main(string[] args)
    {
        int[,] grid = {
            { 0, 0, 0 },
            { 0, 1, 0 },
            { 0, 0, 0 }
        };

        Console.WriteLine(uniquePaths(grid));
    }
}

//Driver Code Ends
JavaScript
// Helper function to find unique paths recursively
function uniPathRec(i, j, grid) {
    let r = grid.length, c = grid[0].length;

    // If out of bounds, return 0
    if (i === r || j === c) {
        return 0;
    }

    // If cell is an obstacle, return 0
    if (grid[i][j] === 1) {
        return 0;
    }

    // If reached the bottom-right cell, return 1
    if (i === r - 1 && j === c - 1) {
        return 1;
    }

    // Recur for the cell below and the cell to the right
    return uniPathRec(i + 1, j, grid) +
           uniPathRec(i, j + 1, grid);
}

// Function to find unique paths with obstacles
function uniquePaths(grid) {
    return uniPathRec(0, 0, grid);
}


//Driver Code Starts
// Driver code
let grid = [
    [0, 0, 0],
    [0, 1, 0],
    [0, 0, 0]
];

console.log(uniquePaths(grid));

//Driver Code Ends

Output
2

[Better Approach 1] Using Top-Down DP(Memoization) - O(n*m) Time and O(n*m) Space

The recursive solution repeatedly solves the same subproblems.. To avoid this, we use memoization, where the answer for each cell is stored in a DP array. Before computing the number of paths from a cell, we first check if its result is already available in the DP array. If yes, we return the stored value; otherwise, we compute it recursively, store it, and return it. This ensures that each cell is processed only once.

  • Create a n × m DP array and initialize all cells with -1.
  • Start recursion from the top-left cell (0, 0).
  • If the current cell is invalid or blocked, return 0.
  • If the destination cell is reached, return 1.
  • If the answer for the current cell is already stored in DP, return it.
  • Otherwise, recursively compute the paths by moving down and right.
  • Store the result in DP and return it.
C++
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;
//Driver Code Ends


// Helper function to find unique paths
int uniPathRec(int i, int j, vector<vector<int>>& grid, 
vector<vector<int>>& dp) {
    int r = grid.size(), c = grid[0].size();
    
    // If out of bounds, return 0
    if(i == r || j == c) {
        return 0;
    }
    
    // If cell is an obstacle, return 0
    if(grid[i][j] == 1) {
        return 0;
    }
    
    // If reached the bottom-right cell, return 1
    if(i == r-1 && j == c-1) {
        return 1;
    }
    
    // If already computed, return the stored result
    if(dp[i][j] != -1) {
        return dp[i][j];
    }
    
    // Compute and store the result
    dp[i][j] = uniPathRec(i+1, j, grid, dp) + 
                 uniPathRec(i, j+1, grid, dp);
    
    return dp[i][j];
}

// Function to find unique paths with obstacles
int uniquePaths(vector<vector<int>>& grid) {
    int n = grid.size(), m = grid[0].size();

    vector<vector<int>> dp(n, vector<int>(m, -1));
    
    return uniPathRec(0, 0, grid, dp);
}

//Driver Code Starts

int main() {
    vector<vector<int>> grid = {
        { 0, 0, 0 },
        { 0, 1, 0 },
        { 0, 0, 0 }
    };
    
    cout << uniquePaths(grid);
    
    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util. Arrays;

public class GFG {

//Driver Code Ends

    // Helper function to find unique paths
    static int uniPathRec(int i, int j, int[][] grid, int[][] dp) {
        int r = grid.length, c = grid[0].length;

        // If out of bounds, return 0
        if (i == r || j == c) {
            return 0;
        }

        // If cell is an obstacle, return 0
        if (grid[i][j] == 1) {
            return 0;
        }

        // If reached the bottom-right cell, return 1
        if (i == r - 1 && j == c - 1) {
            return 1;
        }

        // If already computed, return the stored result
        if (dp[i][j] != -1) {
            return dp[i][j];
        }

        // Compute and store the result
        dp[i][j] = uniPathRec(i + 1, j, grid, dp) +
                   uniPathRec(i, j + 1, grid, dp);

        return dp[i][j];
    }

    // Function to find unique paths with obstacles
    static int uniquePaths(int[][] grid) {
        int n = grid.length, m = grid[0].length;

        int[][] dp = new int[n][m];
        for (int[] row : dp) Arrays.fill(row, -1);

        return uniPathRec(0, 0, grid, dp);
    }

//Driver Code Starts

    public static void main(String[] args) {

        int[][] grid = {
                {0, 0, 0},
                {0, 1, 0},
                {0, 0, 0}
        };

        System.out.println(uniquePaths(grid));
    }
}

//Driver Code Ends
Python
# Helper function to find unique paths
def uniPathRec(i, j, grid, dp):
    r, c = len(grid), len(grid[0])

    # If out of bounds, return 0
    if i == r or j == c:
        return 0

    # If cell is an obstacle, return 0
    if grid[i][j] == 1:
        return 0

    # If reached the bottom-right cell, return 1
    if i == r - 1 and j == c - 1:
        return 1

    # If already computed, return the stored result
    if dp[i][j] != -1:
        return dp[i][j]

    # Compute and store the result
    dp[i][j] = uniPathRec(i + 1, j, grid, dp) + \
               uniPathRec(i, j + 1, grid, dp)

    return dp[i][j]


# Function to find unique paths with obstacles
def uniquePaths(grid):
    n, m = len(grid), len(grid[0])
    dp = [[-1] * m for _ in range(n)]
    return uniPathRec(0, 0, grid, dp)


#Driver Code Starts

if __name__ == "__main__":
    grid = [
        [0, 0, 0],
        [0, 1, 0],
        [0, 0, 0]
    ]
    
    print(uniquePaths(grid))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GFG
{
//Driver Code Ends

    // Helper function to find unique paths
    static int uniPathRec(int i, int j, int[,] grid, int[,] dp)
    {
        int r = grid.GetLength(0), c = grid.GetLength(1);

        // If out of bounds, return 0
        if (i == r || j == c)
        {
            return 0;
        }

        // If cell is an obstacle, return 0
        if (grid[i, j] == 1)
        {
            return 0;
        }

        // If reached the bottom-right cell, return 1
        if (i == r - 1 && j == c - 1)
        {
            return 1;
        }

        // If already computed, return the stored result
        if (dp[i, j] != -1)
        {
            return dp[i, j];
        }

        // Compute and store the result
        dp[i, j] = uniPathRec(i + 1, j, grid, dp) +
                   uniPathRec(i, j + 1, grid, dp);

        return dp[i, j];
    }

    // Function to find unique paths with obstacles
    static int uniquePaths(int[,] grid)
    {
        int n = grid.GetLength(0), m = grid.GetLength(1);

        int[,] dp = new int[n, m];

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                dp[i, j] = -1;
            }
        }

        return uniPathRec(0, 0, grid, dp);
    }

//Driver Code Starts

    static void Main()
    {
        int[,] grid = new int[,]
        {
            {0, 0, 0},
            {0, 1, 0},
            {0, 0, 0}
        };

        Console.WriteLine(uniquePaths(grid));
    }
}

//Driver Code Ends
JavaScript
// Helper function to find unique paths
function uniPathRec(i, j, grid, dp) {
    let r = grid.length, c = grid[0].length;

    // If out of bounds, return 0
    if (i === r || j === c) {
        return 0;
    }

    // If cell is an obstacle, return 0
    if (grid[i][j] === 1) {
        return 0;
    }

    // If reached the bottom-right cell, return 1
    if (i === r - 1 && j === c - 1) {
        return 1;
    }

    // If already computed, return the stored result
    if (dp[i][j] !== -1) {
        return dp[i][j];
    }

    // Compute and store the result
    dp[i][j] = uniPathRec(i + 1, j, grid, dp) +
               uniPathRec(i, j + 1, grid, dp);

    return dp[i][j];
}

// Function to find unique paths with obstacles
function uniquePaths(grid) {
    let n = grid.length, m = grid[0].length;

    let dp = Array.from({ length: n }, () => Array(m).fill(-1));

    return uniPathRec(0, 0, grid, dp);
}


//Driver Code Starts
//Driver Code
let grid = [
    [0, 0, 0],
    [0, 1, 0],
    [0, 0, 0]
];

console.log(uniquePaths(grid));

//Driver Code Ends

Output
2

[Better Approach 2]Using Bottom-Up DP (Tabulation) – O(n*m) Time and O(n*m) Space

Let dp[i][j] represent the number of valid paths from cell (i, j) to the destination. Since we can move only down or right, the number of paths from a cell is the sum of the paths from the cell below and the cell to its right.

  • The table is filled in an iterative manner from i = n-1 to i = 1 and j = m-1 to j = 1.
  • The dynamic programming relation is as follows:  dp[i][j] = dp[i+1][j] + dp[i][j+1]
C++
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;

//Driver Code Ends

int uniquePaths(vector<vector<int>>& grid) {
    int n = grid.size(), m = grid[0].size();
    
    // If starting or ending cell is an obstacle, return 0
    if(grid[0][0] == 1 || grid[n-1][m-1] == 1) {
        return 0;
    }

    vector<vector<int>> dp(n, vector<int>(m, 0));
    dp[n-1][m-1] = 1;
    
    // Fill the bottom row
    for(int j = m-2; j >= 0; j--) {
        
        // As this is an obstacle, no paths will 
        // exist from this cell.
        if(grid[n-1][j] == 1) {
            break;
        }
        
        // Otherwise, a straight path to 
        // n-1, m-1 exists 
        else {
            dp[n-1][j] = 1;
        }
    }
    
    // Fill the rightmost column
    for(int i = n-2; i >= 0; i--) {
        
        // As this is an obstacle, no paths will 
        // exist from this cell.
        if(grid[i][m-1] == 1) {
            break;
        }
        
        // Otherwise, a straight path to 
        // n-1, m-1 exists 
        else {
            dp[i][m-1] = 1;
        }
    }
    
    // Fill the inner cells bottom-up and right-left
    for(int i = n-2; i >= 0; i--) {
        for(int j = m-2; j >= 0; j--) {
            if(grid[i][j] == 0) {
                
                // Number of paths = sum of paths from the 
                // cell below and the cell to the right
                dp[i][j] = dp[i+1][j] + dp[i][j+1];
            }
        }
    }
    
    return dp[0][0];
}

//Driver Code Starts

int main() {
    vector<vector<int>> grid = {
        { 0, 0, 0 },
        { 0, 1, 0 },
        { 0, 0, 0 }
    };
    
    cout << uniquePaths(grid);
    
    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

public class GFG {

//Driver Code Ends

    static int uniquePaths(int[][] grid) {
        int n = grid.length, m = grid[0].length;

        // If starting or ending cell is an obstacle, return 0
        if(grid[0][0] == 1 || grid[n-1][m-1] == 1) {
            return 0;
        }

        int[][] dp = new int[n][m];
        dp[n-1][m-1] = 1;

        // Fill the bottom row
        for(int j = m-2; j >= 0; j--) {

            // As this is an obstacle, no paths will 
            // exist from this cell.
            if(grid[n-1][j] == 1) {
                break;
            }

            // Otherwise, a straight path to 
            // n-1, m-1 exists 
            else {
                dp[n-1][j] = 1;
            }
        }

        // Fill the rightmost column
        for(int i = n-2; i >= 0; i--) {

            // As this is an obstacle, no paths will 
            // exist from this cell.
            if(grid[i][m-1] == 1) {
                break;
            }

            // Otherwise, a straight path to 
            // n-1, m-1 exists 
            else {
                dp[i][m-1] = 1;
            }
        }

        // Fill the inner cells bottom-up and right-left
        for(int i = n-2; i >= 0; i--) {
            for(int j = m-2; j >= 0; j--) {
                if(grid[i][j] == 0) {

                    // Number of paths = sum of paths from the 
                    // cell below and the cell to the right
                    dp[i][j] = dp[i+1][j] + dp[i][j+1];
                }
            }
        }

        return dp[0][0];
    }

//Driver Code Starts

    public static void main(String[] args) {

        int[][] grid = {
            {0, 0, 0},
            {0, 1, 0},
            {0, 0, 0}
        };

        System.out.println(uniquePaths(grid));
    }
}

//Driver Code Ends
Python
def uniquePaths(grid):
    n, m = len(grid), len(grid[0])

    # If starting or ending cell is an obstacle, return 0
    if grid[0][0] == 1 or grid[n-1][m-1] == 1:
        return 0

    dp = [[0] * m for _ in range(n)]
    dp[n-1][m-1] = 1

    # Fill the bottom row
    for j in range(m-2, -1, -1):

        # As this is an obstacle, no paths will 
        # exist from this cell.
        if grid[n-1][j] == 1:
            break

        # Otherwise, a straight path to 
        # n-1, m-1 exists 
        else:
            dp[n-1][j] = 1

    # Fill the rightmost column
    for i in range(n-2, -1, -1):

        # As this is an obstacle, no paths will 
        # exist from this cell.
        if grid[i][m-1] == 1:
            break

        # Otherwise, a straight path to 
        # n-1, m-1 exists 
        else:
            dp[i][m-1] = 1

    # Fill the inner cells bottom-up and right-left
    for i in range(n-2, -1, -1):
        for j in range(m-2, -1, -1):
            if grid[i][j] == 0:

                # Number of paths = sum of paths from the 
                # cell below and the cell to the right
                dp[i][j] = dp[i+1][j] + dp[i][j+1]

    return dp[0][0]


//Driver Code Starts

if __name__ == "__main__":
    grid = [
        [0, 0, 0],
        [0, 1, 0],
        [0, 0, 0]
    ]
    
    print(uniquePaths(grid))

//Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG
{
//Driver Code Ends

    static int uniquePaths(int[,] grid)
    {
        int n = grid.GetLength(0), m = grid.GetLength(1);

        // If starting or ending cell is an obstacle, return 0
        if (grid[0,0] == 1 || grid[n-1,m-1] == 1)
        {
            return 0;
        }

        int[,] dp = new int[n, m];
        dp[n-1, m-1] = 1;

        // Fill the bottom row
        for (int j = m - 2; j >= 0; j--)
        {
            // As this is an obstacle, no paths will 
            // exist from this cell.
            if (grid[n-1, j] == 1) break;

            // Otherwise, a straight path to 
            // n-1, m-1 exists 
            dp[n-1, j] = 1;
        }

        // Fill the rightmost column
        for (int i = n - 2; i >= 0; i--)
        {
            // As this is an obstacle, no paths will 
            // exist from this cell.
            if (grid[i, m-1] == 1) break;

            // Otherwise, a straight path to 
            // n-1, m-1 exists 
            dp[i, m-1] = 1;
        }

        // Fill the inner cells bottom-up and right-left
        for (int i = n - 2; i >= 0; i--)
        {
            for (int j = m - 2; j >= 0; j--)
            {
                if (grid[i, j] == 0)
                {
                    // Number of paths = sum of paths from the 
                    // cell below and the cell to the right
                    dp[i, j] = dp[i+1, j] + dp[i, j+1];
                }
            }
        }

        return dp[0, 0];
    }

//Driver Code Starts

    static void Main()
    {
        int[,] grid = new int[,]
        {
            {0, 0, 0},
            {0, 1, 0},
            {0, 0, 0}
        };

        Console.WriteLine(uniquePaths(grid));
    }
}

//Driver Code Ends
JavaScript
function uniquePaths(grid) {
    let n = grid.length, m = grid[0].length;

    // If starting or ending cell is an obstacle, return 0
    if (grid[0][0] === 1 || grid[n-1][m-1] === 1) {
        return 0;
    }

    let dp = Array.from({ length: n }, () => Array(m).fill(0));
    dp[n-1][m-1] = 1;

    // Fill the bottom row
    for (let j = m - 2; j >= 0; j--) {

        // As this is an obstacle, no paths will 
        // exist from this cell.
        if (grid[n-1][j] === 1) break;

        // Otherwise, a straight path to 
        // n-1, m-1 exists 
        dp[n-1][j] = 1;
    }

    // Fill the rightmost column
    for (let i = n - 2; i >= 0; i--) {

        // As this is an obstacle, no paths will 
        // exist from this cell.
        if (grid[i][m-1] === 1) break;

        // Otherwise, a straight path to 
        // n-1, m-1 exists 
        dp[i][m-1] = 1;
    }

    // Fill the inner cells bottom-up and right-left
    for (let i = n - 2; i >= 0; i--) {
        for (let j = m - 2; j >= 0; j--) {
            if (grid[i][j] === 0) {

                // Number of paths = sum of paths from the 
                // cell below and the cell to the right
                dp[i][j] = dp[i+1][j] + dp[i][j+1];
            }
        }
    }

    return dp[0][0];
}


//Driver Code Starts
//Driver Code
let grid = [
    [0, 0, 0],
    [0, 1, 0],
    [0, 0, 0]
];

console.log(uniquePaths(grid));

//Driver Code Ends

Output
2

[Expected Approach] Using Space Optimized DP – O(m*n) Time and O(n) Space

In previous approach of dynamic programming we have derive the relation between states as given below:

  • dp[i][j] = dp[i+1][j] + dp[i][j+1]

If we observe that for calculating current dp[i][j] state we only need next row dp[i+1][j] and next cells value. There is no need to store all the next states just one next state is used to compute result.

C++
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;

//Driver Code Ends

int uniquePaths(vector<vector<int>>& grid) {
    int n = grid.size(), m = grid[0].size();
    
    // If starting or ending cell is an obstacle, return 0
    if(grid[0][0] == 1 || grid[n-1][m-1] == 1) {
        return 0;
    }

    vector<int> dp(m, 0);

    dp[m-1] = 1;
    
    // Fill the bottom row first
    for(int j = m-2; j >= 0; j--) {
        
        // As this is an obstacle, no paths will 
        // exist from this cell.
        if(grid[n-1][j] == 1) {
            dp[j] = 0;
        }
        
        // Otherwise, a straight path to 
        // n-1, m-1 exists 
        else {
            dp[j] = dp[j+1];
        }
    }
    
    // Process each row from bottom to top
    for(int i = n-2; i >= 0; i--) {
        
        // Process the rightmost column of the current row
        if(grid[i][m-1] == 1) {
            dp[m-1] = 0;
        }
        
        // Process each cell from right to left
        for(int j = m-2; j >= 0; j--) {
            
            // If current cell is an obstacle, paths = 0
            if(grid[i][j] == 1) {
                dp[j] = 0;
            }
            
            // Otherwise, paths = sum of right and down paths
            else {
                dp[j] = dp[j] + dp[j+1];
            }
        }
    }
    
    return dp[0];
}

//Driver Code Starts

int main() {
    vector<vector<int>> grid = {
        { 0, 0, 0 },
        { 0, 1, 0 },
        { 0, 0, 0 }
    };
    
    cout << uniquePaths(grid);
    
    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

public class GFG {

//Driver Code Ends

    static int uniquePaths(int[][] grid) {
        int n = grid.length, m = grid[0].length;
        
        // If starting or ending cell is an obstacle, return 0
        if(grid[0][0] == 1 || grid[n-1][m-1] == 1) {
            return 0;
        }

        int[] dp = new int[m];

        dp[m-1] = 1;
        
        // Fill the bottom row first
        for(int j = m-2; j >= 0; j--) {
            
            // As this is an obstacle, no paths will 
            // exist from this cell.
            if(grid[n-1][j] == 1) {
                dp[j] = 0;
            }
            
            // Otherwise, a straight path to 
            // n-1, m-1 exists 
            else {
                dp[j] = dp[j+1];
            }
        }
        
        // Process each row from bottom to top
        for(int i = n-2; i >= 0; i--) {
            
            // Process the rightmost column of the current row
            if(grid[i][m-1] == 1) {
                dp[m-1] = 0;
            }
            
            // Process each cell from right to left
            for(int j = m-2; j >= 0; j--) {
                
                // If current cell is an obstacle, paths = 0
                if(grid[i][j] == 1) {
                    dp[j] = 0;
                }
                
                // Otherwise, paths = sum of right and down paths
                else {
                    dp[j] = dp[j] + dp[j+1];
                }
            }
        }
        
        return dp[0];
    }

//Driver Code Starts

    public static void main(String[] args) {
        int[][] grid = {
            { 0, 0, 0 },
            { 0, 1, 0 },
            { 0, 0, 0 }
        };

        System.out.println(uniquePaths(grid));
    }
}

//Driver Code Ends
Python
def uniquePaths(grid):
    n = len(grid)
    m = len(grid[0])
    
    # If starting or ending cell is an obstacle, return 0
    if grid[0][0] == 1 or grid[n-1][m-1] == 1:
        return 0

    dp = [0] * m

    dp[m-1] = 1
    
    # Fill the bottom row first
    for j in range(m-2, -1, -1):
        
        # As this is an obstacle, no paths will 
        # exist from this cell.
        if grid[n-1][j] == 1:
            dp[j] = 0
        
        # Otherwise, a straight path to 
        # n-1, m-1 exists 
        else:
            dp[j] = dp[j+1]
    
    # Process each row from bottom to top
    for i in range(n-2, -1, -1):
        
        # Process the rightmost column of the current row
        if grid[i][m-1] == 1:
            dp[m-1] = 0
        
        # Process each cell from right to left
        for j in range(m-2, -1, -1):
            
            # If current cell is an obstacle, paths = 0
            if grid[i][j] == 1:
                dp[j] = 0
            
            # Otherwise, paths = sum of right and down paths
            else:
                dp[j] = dp[j] + dp[j+1]
    
    return dp[0]


#Driver Code Starts
if __name__ == "__main__":
    grid = [
        [0,0,0],
        [0,1,0],
        [0,0,0]
    ]
    
    print(uniquePaths(grid))

#Driver Code Ends
C#
//Driver Code Starts
using System;

public class GFG {

//Driver Code Ends

    public static int uniquePaths(int[,] grid) {
        int n = grid.GetLength(0), m = grid.GetLength(1);
        
        // If starting or ending cell is an obstacle, return 0
        if(grid[0,0] == 1 || grid[n-1, m-1] == 1) {
            return 0;
        }

        int[] dp = new int[m];

        dp[m-1] = 1;
        
        // Fill the bottom row first
        for(int j = m-2; j >= 0; j--) {
            
            // As this is an obstacle, no paths will 
            // exist from this cell.
            if(grid[n-1, j] == 1) {
                dp[j] = 0;
            }
            
            // Otherwise, a straight path to 
            // n-1, m-1 exists 
            else {
                dp[j] = dp[j+1];
            }
        }
        
        // Process each row from bottom to top
        for(int i = n-2; i >= 0; i--) {
            
            // Process the rightmost column of the current row
            if(grid[i, m-1] == 1) {
                dp[m-1] = 0;
            }
            
            // Process each cell from right to left
            for(int j = m-2; j >= 0; j--) {
                
                // If current cell is an obstacle, paths = 0
                if(grid[i, j] == 1) {
                    dp[j] = 0;
                }
                
                // Otherwise, paths = sum of right and down paths
                else {
                    dp[j] = dp[j] + dp[j+1];
                }
            }
        }
        
        return dp[0];
    }

//Driver Code Starts

    public static void Main() {
        int[,] grid = {
            { 0, 0, 0 },
            { 0, 1, 0 },
            { 0, 0, 0 }
        };
        
        Console.WriteLine(uniquePaths(grid));
    }
}

//Driver Code Ends
JavaScript
function uniquePaths(grid) {
    let n = grid.length, m = grid[0].length;
    
    // If starting or ending cell is an obstacle, return 0
    if (grid[0][0] === 1 || grid[n-1][m-1] === 1) {
        return 0;
    }

    let dp = Array(m).fill(0);

    dp[m-1] = 1;
    
    // Fill the bottom row first
    for (let j = m-2; j >= 0; j--) {
        
        // As this is an obstacle, no paths will 
        // exist from this cell.
        if (grid[n-1][j] === 1) {
            dp[j] = 0;
        }
        
        // Otherwise, a straight path to 
        // n-1, m-1 exists 
        else {
            dp[j] = dp[j+1];
        }
    }
    
    // Process each row from bottom to top
    for (let i = n-2; i >= 0; i--) {
        
        // Process the rightmost column of the current row
        if (grid[i][m-1] === 1) {
            dp[m-1] = 0;
        }
        
        // Process each cell from right to left
        for (let j = m-2; j >= 0; j--) {
            
            // If current cell is an obstacle, paths = 0
            if (grid[i][j] === 1) {
                dp[j] = 0;
            }
            
            // Otherwise, paths = sum of right and down paths
            else {
                dp[j] = dp[j] + dp[j+1];
            }
        }
    }
    
    return dp[0];
}


//Driver Code Starts
//Driver Code
let grid = [
    [0,0,0],
    [0,1,0],
    [0,0,0]
];

console.log(uniquePaths(grid));

//Driver Code Ends

Output
2
Comment