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++
#include<bits/stdc++.h>
using namespace std;
int UniquePathHelper( int i, int j, int r, int c, vector<vector< int >>& A){
if (i == r || j == c){
return 0 ;
}
if (A[i][j] == 1){
return 0 ;
}
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) ;
}
int main()
{
vector<vector< int >> A = { { 0, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 } };
cout << uniquePathsWithObstacles(A) << " \n" ;
}
|
Java
import java.io.*;
class GFG {
static int UniquePathHelper( int i, int j, int r, int c,
int [][] A)
{
if (i == r || j == c) {
return 0 ;
}
if (A[i][j] == 1 ) {
return 0 ;
}
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);
}
public static void main(String[] args)
{
int [][] A
= { { 0 , 0 , 0 }, { 0 , 1 , 0 }, { 0 , 0 , 0 } };
System.out.print(uniquePathsWithObstacles(A));
}
}
|
Python3
def UniquePathHelper(i, j, r, c, A):
if (i = = r or j = = c):
return 0
if (A[i][j] = = 1 ):
return 0
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)
A = [ [ 0 , 0 , 0 ],
[ 0 , 1 , 0 ],
[ 0 , 0 , 0 ] ]
print (uniquePathsWithObstacles(A))
|
C#
using System;
class Program
{
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)
{
if (i == r || j == c) {
return 0;
}
if (A[i, j] == 1) {
return 0;
}
if (i == r - 1 && j == c - 1) {
return 1;
}
return UniquePathHelper(i + 1, j, r, c, A)
+ UniquePathHelper(i, j + 1, r, c, A);
}
}
|
Javascript
<script>
function UniquePathHelper(i, j, r, c, A){
if (i == r || j == c)
return 0
if (A[i][j] == 1)
return 0
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)
}
let A = [ [ 0, 0, 0 ],
[ 0, 1, 0 ],
[ 0, 0, 0 ] ]
document.write(uniquePathsWithObstacles(A))
</script>
|
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++
#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)
{
if (i == r || j == c) {
return 0;
}
if (A[i][j] == 1) {
return 0;
}
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();
vector<vector< int > > paths(r, vector< int >(c, -1));
return UniquePathHelper(0, 0, r, c, A, paths);
}
int main()
{
vector<vector< int > > A
= { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };
cout << uniquePathsWithObstacles(A) << " \n" ;
}
|
Java
import 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;
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)
{
if (i == r || j == c) {
return 0 ;
}
else if (A[i][j] == 1 ) {
return 0 ;
}
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);
}
}
}
|
Python3
def UniquePathHelper(i, j, r, c, A, paths):
if (i = = r or j = = c):
return 0
if (A[i][j] = = 1 ):
return 0
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 ])
paths = [[ - 1 for i in range (c)] for j in range (r)]
return UniquePathHelper( 0 , 0 , r, c, A, paths)
A = [[ 0 , 0 , 0 ], [ 0 , 1 , 0 ], [ 0 , 0 , 0 ]]
print (uniquePathsWithObstacles(A))
|
C#
using System;
class Program {
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);
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)
{
if (i == r || j == c) {
return 0;
}
if (A[i, j] == 1) {
return 0;
}
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);
}
}
|
Javascript
<script>
function UniquePathHelper(i, j, r, c, A, paths)
{
if (i == r || j == c) {
return 0;
}
if (paths[i][j] == 1) {
return 0;
}
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;
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);
}
let A = [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 0 ] ]
document.write(uniquePathsWithObstacles(A))
</script>
|
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++
#include<bits/stdc++.h>
using namespace std;
int uniquePathsWithObstacles(vector<vector< int >>& A)
{
int r = A.size(), c = A[0].size();
vector<vector< int >> paths(r, vector< int >(c, 0));
if (A[0][0] == 0)
paths[0][0] = 1;
for ( int i = 1; i < r; i++)
{
if (A[i][0] == 0)
paths[i][0] = paths[i-1][0];
}
for ( int j = 1; j < c; j++)
{
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 (A[i][j] == 0)
paths[i][j] = paths[i - 1][j] +
paths[i][j - 1];
}
}
return paths[r - 1];
}
int main()
{
vector<vector< int >> A = { { 0, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 } };
cout << uniquePathsWithObstacles(A) << " \n" ;
}
|
Java
public class Main
{
static int uniquePathsWithObstacles( int [][] A)
{
int r = 3 , c = 3 ;
int [][] paths = new int [r];
for ( int i = 0 ; i < r; i++)
{
for ( int j = 0 ; j < c; j++)
{
paths[i][j] = 0 ;
}
}
if (A[ 0 ][ 0 ] == 0 )
paths[ 0 ][ 0 ] = 1 ;
for ( int i = 1 ; i < r; i++)
{
if (A[i][ 0 ] == 0 )
paths[i][ 0 ] = paths[i - 1 ][ 0 ];
}
for ( int j = 1 ; j < c; j++)
{
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 (A[i][j] == 0 )
paths[i][j] = paths[i - 1 ][j] +
paths[i][j - 1 ];
}
}
return paths[r - 1 ];
}
public static void main(String[] args) {
int [][] A = { { 0 , 0 , 0 },
{ 0 , 1 , 0 },
{ 0 , 0 , 0 } };
System.out.print(uniquePathsWithObstacles(A));
}
}
|
Python
def uniquePathsWithObstacles(A):
paths = [[ 0 ] * len (A[ 0 ]) for i in A]
if A[ 0 ][ 0 ] = = 0 :
paths[ 0 ][ 0 ] = 1
for i in range ( 1 , len (A)):
if A[i][ 0 ] = = 0 :
paths[i][ 0 ] = paths[i - 1 ][ 0 ]
for j in range ( 1 , len (A[ 0 ])):
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 A[i][j] = = 0 :
paths[i][j] = paths[i - 1 ][j] + paths[i][j - 1 ]
return paths[ - 1 ][ - 1 ]
A = [[ 0 , 0 , 0 ], [ 0 , 1 , 0 ], [ 0 , 0 , 0 ]]
print (uniquePathsWithObstacles(A))
|
C#
using System;
class GFG {
static int uniquePathsWithObstacles( int [,] A)
{
int r = 3, c = 3;
int [,] paths = new int [r,c];
for ( int i = 0; i < r; i++)
{
for ( int j = 0; j < c; j++)
{
paths[i, j] = 0;
}
}
if (A[0, 0] == 0)
paths[0, 0] = 1;
for ( int i = 1; i < r; i++)
{
if (A[i, 0] == 0)
paths[i, 0] = paths[i - 1, 0];
}
for ( int j = 1; j < c; j++)
{
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 (A[i, j] == 0)
paths[i, j] = paths[i - 1, j] +
paths[i, j - 1];
}
}
return paths[r - 1, c - 1];
}
static void Main() {
int [,] A = { { 0, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 } };
Console.WriteLine(uniquePathsWithObstacles(A));
}
}
|
Javascript
<script>
function uniquePathsWithObstacles(A)
{
let r = 3, c = 3;
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;
}
}
if (A[0][0] == 0)
paths[0][0] = 1;
for (let i = 1; i < r; i++)
{
if (A[i][0] == 0)
paths[i][0] = paths[i - 1][0];
}
for (let j = 1; j < c; j++)
{
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 (A[i][j] == 0)
paths[i][j] = paths[i - 1][j] +
paths[i][j - 1];
}
}
return paths[r - 1];
}
let A = [ [ 0, 0, 0 ],
[ 0, 1, 0 ],
[ 0, 0, 0 ] ];
document.write(uniquePathsWithObstacles(A));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int uniquePathsWithObstacles(vector<vector< int > >& A)
{
int r = A.size();
int c = A[0].size();
if (A[0][0])
return 0;
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;
}
}
for ( int i = 1; i < r; i++) {
if (A[i][0] == 0) {
A[i][0] = A[i - 1][0];
}
else {
A[i][0] = 0;
}
}
for ( int i = 1; i < r; i++) {
for ( int j = 1; j < c; j++) {
if (A[i][j] == 0) {
A[i][j] = A[i - 1][j] + A[i][j - 1];
}
else {
A[i][j] = 0;
}
}
}
return A[r - 1];
}
int main()
{
vector<vector< int > > A
= { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } };
cout << uniquePathsWithObstacles(A) << "\n" ;
return 0;
}
|
Java
import java.io.*;
class GFG {
static int uniquePathsWithObstacles( int [][] A)
{
int r = A.length;
int c = A[ 0 ].length;
if (A[ 0 ][ 0 ] != 0 )
return 0 ;
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 ;
}
}
for ( int i = 1 ; i < r; i++) {
if (A[i][ 0 ] == 0 ) {
A[i][ 0 ] = A[i - 1 ][ 0 ];
}
else {
A[i][ 0 ] = 0 ;
}
}
for ( int i = 1 ; i < r; i++) {
for ( int j = 1 ; j < c; j++) {
if (A[i][j] == 0 ) {
A[i][j] = A[i - 1 ][j] + A[i][j - 1 ];
}
else {
A[i][j] = 0 ;
}
}
}
return A[r - 1 ];
}
public static void main(String[] args)
{
int [][] A
= { { 0 , 0 , 0 }, { 0 , 1 , 0 }, { 0 , 0 , 0 } };
System.out.print(uniquePathsWithObstacles(A));
}
}
|
Python3
def uniquePathsWithObstacles(A):
r = len (A)
c = len (A[ 0 ])
if (A[ 0 ][ 0 ]):
return 0
A[ 0 ][ 0 ] = 1
for j in range ( 1 ,c):
if (A[ 0 ][j] = = 0 ):
A[ 0 ][j] = A[ 0 ][j - 1 ]
else :
A[ 0 ][j] = 0
for i in range ( 1 ,r):
if (A[i][ 0 ] = = 0 ):
A[i][ 0 ] = A[i - 1 ][ 0 ]
else :
A[i][ 0 ] = 0
for i in range ( 1 ,r):
for j in range ( 1 ,c):
if (A[i][j] = = 0 ):
A[i][j] = A[i - 1 ][j] + A[i][j - 1 ]
else :
A[i][j] = 0
return A[r - 1 ]
A = [ [ 0 , 0 , 0 ], [ 0 , 1 , 0 ], [ 0 , 0 , 0 ] ]
print (uniquePathsWithObstacles(A))
|
C#
using System;
using System.Collections.Generic;
class Program {
static int uniquePathsWithObstacles( int [, ] A)
{
int r = A.GetLength(0);
int c = A.GetLength(1);
if (A[0, 0] != 0)
return 0;
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;
}
}
for ( int i = 1; i < r; i++) {
if (A[i, 0] == 0) {
A[i, 0] = A[i - 1, 0];
}
else {
A[i, 0] = 0;
}
}
for ( int i = 1; i < r; i++) {
for ( int j = 1; j < c; j++) {
if (A[i, j] == 0) {
A[i, j] = A[i - 1, j] + A[i, j - 1];
}
else {
A[i, j] = 0;
}
}
}
return A[r - 1, c - 1];
}
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));
}
}
|
Javascript
<script>
function uniquePathsWithObstacles(A){
let r = A.length
let c = A[0].length
if (A[0][0])
return 0
A[0][0] = 1
for (let j = 1; j < c; j++)
{
if (A[0][j] == 0)
A[0][j] = A[0][j - 1]
else
A[0][j] = 0
}
for (let i = 1; i < r; i++){
if (A[i][0] == 0)
A[i][0] = A[i - 1][0]
else
A[i][0] = 0
}
for (let i = 1; i < r; i++){
for (let j = 1; j < c; j++){
if (A[i][j] == 0)
A[i][j] = A[i - 1][j] + A[i][j - 1]
else
A[i][j] = 0
}
}
return A[r - 1]
}
let A = [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 0 ] ]
document.write(uniquePathsWithObstacles(A), "</br>" )
</script>
|
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 long
using 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));
path(dp, grid, 0, 0);
if (dp[0][0] == -1)
return 0;
return dp[0][0];
}
signed main()
{
vector<vector< int > > v{ { 0, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 0 } };
cout << uniquePathsWithObstacles(v) << " \n" ;
return 0;
}
|
Java
import 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));
}
}
|
Python3
def 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 ]
grid = [[ 0 , 0 , 0 ], [ 0 , 1 , 0 ], [ 0 , 0 , 0 ]]
print (uniquePathsWithObstacles(grid))
|
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);
path(dp,grid,0,0);
if (dp[0][0]==-1)
return 0;
return dp[0][0];
}
let 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;
}
}
}
|
Time Complexity: O(M*N),For traversing all possible ways.
Auxiliary Space: O(M*N),For storing in 2D Dp Vector.
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!