Open In App

Valid paths in a grid in Python

Last Updated : 03 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. Start from the top-left cell (0, 0).
  2. 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.
  3. 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));

Output
1
2

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.

Valid paths in a grid using Dynamic Programming (DP):

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:

  1. Initialize a 2D dp array of the same size as the grid.
  2. 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
  3. 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)) 

Output
1
2

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads