Unique paths in a Grid with Obstacles (original) (raw)
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.
**Input: grid[][] = {{1, 0, 1}}
**Output: 0
**Explanation: There is no possible path to reach the end.
Table of Content
- [Naive Approach] Using Recursion - O(2^(n*m)) Time and O(n+m) Space
- [Better Approach 1] Using Top-Down DP(Memoization) - O(n*m) Time and O(n*m) Space
- [Better Approach 2]Using Bottom-Up DP (Tabulation) – O(n*m) Time and O(n*m) Space
- [Expected Approach] Using Space Optimized DP – O(m*n) Time and O(n) Space
[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 #include using namespace std;
//Driver Code Ends
// Helper function to find unique paths recursively int uniPathRec(int i, int j, vector<vector>& 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>& 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
`
[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 #include using namespace std; //Driver Code Ends
// Helper function to find unique paths int uniPathRec(int i, int j, vector<vector>& grid, vector<vector>& 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>& 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> 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
`
[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 #include using namespace std;
//Driver Code Ends
int uniquePaths(vector<vector>& 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> 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
`
[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 #include using namespace std;
//Driver Code Ends
int uniquePaths(vector<vector>& 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> 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
`
