Valid paths in a grid in Python
Last Updated :
03 May, 2024
Given a 2D grid of 0s (obstacles) and 1s (valid paths), find the number of valid paths from the top-left corner to the bottom-right corner. You can only move down or right.
Examples:
Input: grid = [ [1, 1, 1], [1, 0, 1], [1, 1, 1]]
Output: 2
Input: grid = [ [1, 1], [1, 1]]
Output: 1
Valid paths in a grid using Recursion:
Idea is to use a recursive approach to explore all possible paths from the starting cell to the ending cell and check if the unique and valid paths.
Steps to solve the problem:
- Start from the top-left cell
(0, 0)
. - Recursively explore two paths:
- Move down from
(i, j)
to (i+1, j)
if it’s a valid path. - Move right from
(i, j)
to (i, j+1)
if it’s a valid path.
- If
(i, j)
reaches the bottom-right cell (m-1, n-1)
, increment the count of valid paths.
Below is the implementation of the approach:
C++
#include <iostream>
#include <vector>
using namespace std;
// Function to count the number of paths from (i, j) to
// bottom-right
int countPaths(const vector<vector<int> >& grid, int i,
int j)
{
// Base case: if out of bounds or obstacle encountered
if (i >= grid.size() || j >= grid[0].size()
|| grid[i][j] == 0)
return 0;
// If reached the bottom-right cell
if (i == grid.size() - 1 && j == grid[0].size() - 1)
return 1;
// Move down and right
return countPaths(grid, i + 1, j)
+ countPaths(grid, i, j + 1);
}
int main()
{
vector<vector<int> > grid1 = { { 1, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 1 } };
vector<vector<int> > grid2 = { { 1, 1 }, { 1, 1 } };
cout << countPaths(grid1, 0, 0)
<< endl; // Output for grid1
cout << countPaths(grid2, 0, 0)
<< endl; // Output for grid2
return 0;
}
// This code is contributed by Ayush Mishra
Java
public class Main {
public static int countPathsNaive(int[][] grid, int i,
int j)
{
// Base case: if out of bounds or obstacle
// encountered
if (i >= grid.length || j >= grid[0].length
|| grid[i][j] == 0) {
return 0;
}
// If reached the bottom-right cell
if (i == grid.length - 1
&& j == grid[0].length - 1) {
return 1;
}
// Move down and right
return countPathsNaive(grid, i + 1, j)
+ countPathsNaive(grid, i, j + 1);
}
public static void main(String[] args)
{
int[][] grid1 = { { 1, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 1 } };
System.out.println(countPathsNaive(grid1, 0, 0));
int[][] grid2 = { { 1, 1 }, { 1, 1 } };
System.out.println(countPathsNaive(grid2, 0, 0));
}
}
Python
def count_paths_naive(grid, i, j):
# Base case: if out of bounds or obstacle encountered
if i >= len(grid) or j >= len(grid[0]) or grid[i][j] == 0:
return 0
# If reached the bottom-right cell
if i == len(grid) - 1 and j == len(grid[0]) - 1:
return 1
# Move down and right
return count_paths_naive(grid, i+1, j) + count_paths_naive(grid, i, j+1)
grid1 = [
[1, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 1, 0],
[0, 1, 1, 1]
]
print(count_paths_naive(grid1, 0, 0))
grid2 = [
[1, 1],
[1, 1]
]
print(count_paths_naive(grid2, 0, 0))
JavaScript
function countPathsNaive(grid, i, j) {
// Base case: if out of bounds or obstacle encountered
if (i >= grid.length || j >= grid[0].length || grid[i][j] === 0) {
return 0;
}
// If reached the bottom-right cell
if (i === grid.length - 1 && j === grid[0].length - 1) {
return 1;
}
// Move down and right
return countPathsNaive(grid, i + 1, j) + countPathsNaive(grid, i, j + 1);
}
let grid1 = [
[1, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 1, 0],
[0, 1, 1, 1]
];
console.log(countPathsNaive(grid1, 0, 0));
let grid2 = [
[1, 1],
[1, 1]
];
console.log(countPathsNaive(grid2, 0, 0));
Time Complexity: O(2m+n) where m is the number of rows and n is the number of columns.
Auxiliary Space: O(m+n) for the recursion stack.
Use a 2D dp
array to store the number of valid paths to reach each cell in the grid. The DP approach is significantly more efficient than the naïve recursive approach because it avoids redundant computations by storing the solutions to subproblems in a 2D array.
Steps to solve this problem:
- Initialize a 2D
dp
array of the same size as the grid. - Initialize the first row and first column of
dp
:dp[i][0] = 1
if grid[i][0] == 1
, else dp[i][0] = 0
dp[0][j] = 1
if grid[0][j] == 1
, else dp[0][j] = 0
- For each cell
(i, j)
in the grid, update dp[i][j]
as:dp[i][j] = dp[i-1][j] + dp[i][j-1]
if grid[i][j] == 1
, else dp[i][j] = 0
Below is the implementation of the approach:
Python
def count_paths_dp(grid):
rows, cols = len(grid), len(grid[0])
# Initialize dp array
dp = [[0] * cols for _ in range(rows)]
# Initialize the first row and first column
for i in range(rows):
if grid[i][0] == 1:
dp[i][0] = 1
else:
break
for j in range(cols):
if grid[0][j] == 1:
dp[0][j] = 1
else:
break
# Fill the dp array
for i in range(1, rows):
for j in range(1, cols):
if grid[i][j] == 1:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[rows-1][cols-1]
grid1 = [
[1, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 1, 0],
[0, 1, 1, 1]
]
print(count_paths_dp(grid1))
grid2 = [
[1, 1],
[1, 1]
]
print(count_paths_dp(grid2))
Time Complexity: O(m×n) where m is the number of rows and n is the number of columns.
Auxiliary Space: O(m×n) for the creating dp
array
Share your thoughts in the comments
Please Login to comment...