Open In App

Count Paths to Exit Matrix Boundary with K Moves

Last Updated : 17 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given three positive integers M, N, K, startRow, and startColumn, there is an M x N matrix and we are at position [startRow, startColumn] within this matrix. We can move at most K times in any four directions: UP, DOWN, LEFT, and RIGHT, and continue moving until we cross the matrix boundary. The task is to calculate the number of paths we can take to move out of the matrix boundary. Return the count modulo 109 + 7.

Examples:

Input: M = 2, N = 2, K = 2, startRow = 0, startColumn = 0
Output: 6
Explanation: Starting from (0, 0), the paths to move out of the matrix in 2 moves are:

  • (0, 0) -> (-1, 0)
  • (0, 0) -> (0, -1)
  • (0, 0) -> (0, 1) -> (0, 2)
  • (0, 0) -> (0, 1) -> (-1, 1)
  • (0, 0) -> (1, 0) -> (2, 0)
  • (0, 0) -> (1, 0) -> (1, -1)

Input: M = 1, N = 3, K = 3, startRow = 0, startColumn = 1
Output: 12
Explanation: Starting from (0, 1), the paths to move out of the matrix in 3 moves are:

  • (0, 1) -> (-1, 1)
  • (0, 1) -> (1, 1)
  • (0, 1) -> (0, 0) -> (-1, 0)
  • (0, 1) -> (0, 0) -> (1, 0)
  • (0, 1) -> (0, 0) -> (0, -1)
  • (0, 1) -> (0, 0) -> (0, 1) -> (-1, 1)
  • (0, 1) -> (0, 0) -> (0, 1) -> (1, 1)
  • (0, 1) -> (0, 2) -> (-1, 2)
  • (0, 1) -> (0, 2) -> (1, 2)
  • (0, 1) -> (0, 2) -> (0, 3)
  • (0, 1) -> (0, 2) -> (0, 1) -> (-1, 1)
  • (0, 1) -> (0, 2) -> (0, 1) -> (1, 1)

Approach: The problem can be solved by using the following approach:

The idea is to recursively explore all possible directions (UP, DOWN, LEFT, and RIGHT), while tracking the remaining moves and the position. The base cases are when we reach out of bounds or when we have exhausted all K moves. To optimize and avoid redundant calculations, we can uses memoization to store and reuse intermediate results. Finally, returns the count of valid paths.

Step to solve the problem:

  • Base cases: If we move out of bounds, return 1 (indicating a valid path is found).
  • If K is 0, return 0 (indicating no valid path can be found).
  • Check if the result for the current state exists in the dp[][] array. If so, return it.
  • Recursively calculate the number of paths by moving in all four directions (up, down, left, right), decrementing k by 1 in each move.
  • Store the result in the dp[][] array for the current state and return it.

Below is the implementation of the above approach:

C++




// C++ Code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
int dp[52][52][52];
int mod = 1e9 + 7;
 
int findPaths(int startRow, int startCol, int k, int m,
              int n)
{
    // Base cases
    if (startRow >= m || startRow < 0 || startCol >= n
        || startCol < 0)
        // We have moved out of the matrix,
        // one path found.
        return 1;
 
    if (k == 0)
        // All moves exhausted
        return 0;
 
    if (dp[startRow][startCol][k] != -1)
        // Return result if already calculated
        return dp[startRow][startCol][k];
 
    // Calculate the number of paths by recursively
    // exploring all four directions.
    long long down
        = findPaths(startRow + 1, startCol, k - 1, m, n);
    long long up
        = findPaths(startRow - 1, startCol, k - 1, m, n);
    long long right
        = findPaths(startRow, startCol + 1, k - 1, m, n);
    long long left
        = findPaths(startRow, startCol - 1, k - 1, m, n);
 
    // Store and return the result
    return dp[startRow][startCol][k]
           = (((down + up) % mod + right) % mod + left)
             % mod;
}
 
// Driver code
int main()
{
 
    int m = 2, n = 2, k = 2, startRow = 0, startColumn = 0;
    // Initialize the DP array with -1.
    memset(dp, -1, sizeof(dp));
 
    // Call the findPaths function with the given
    // parameters.
    cout << findPaths(startRow, startColumn, k, m, n);
 
    return 0;
}


Java




import java.util.*;
 
public class GFG {
 
    static long[][][] dp;
    static int mod = 1000000007;
 
    public static void main(String[] args) {
        int m = 2, n = 2, k = 2, startRow = 0, startCol = 0;
 
        // Initialize the DP array with -1.
        dp = new long[52][52][52];
        for (int i = 0; i < 52; i++) {
            for (int j = 0; j < 52; j++) {
                Arrays.fill(dp[i][j], -1);
            }
        }
 
        // Call the findPaths function with the given parameters.
        System.out.println(findPaths(startRow, startCol, k, m, n));
    }
 
    static long findPaths(int startRow, int startCol, int k, int m, int n) {
        // Base cases
        if (startRow >= m || startRow < 0 || startCol >= n || startCol < 0) {
            // We have moved out of the matrix, one path found.
            return 1;
        }
 
        if (k == 0) {
            // All moves exhausted
            return 0;
        }
 
        if (dp[startRow][startCol][k] != -1) {
            // Return result if already calculated
            return dp[startRow][startCol][k];
        }
 
        // Calculate the number of paths by recursively exploring all four directions.
        long down = findPaths(startRow + 1, startCol, k - 1, m, n);
        long up = findPaths(startRow - 1, startCol, k - 1, m, n);
        long right = findPaths(startRow, startCol + 1, k - 1, m, n);
        long left = findPaths(startRow, startCol - 1, k - 1, m, n);
 
        // Store and return the result
        return dp[startRow][startCol][k] = (((down + up) % mod + right) % mod + left) % mod;
    }
}


Python3




# Python code for the above approach:
 
mod = 1e9 + 7
# Function to find the number of paths
def find_paths(start_row, start_col, k, m, n):
    # Base cases
    if start_row >= m or start_row < 0 or start_col >= n or start_col < 0:
        # We have moved out of the matrix,
        # one path found.
        return 1
 
    if k == 0:
        # All moves exhausted
        return 0
 
    if dp[start_row][start_col][k] != -1:
        # Return result if already calculated
        return dp[start_row][start_col][k]
 
    # Calculate the number of paths by recursively
    # exploring all four directions.
    down = find_paths(start_row + 1, start_col, k - 1, m, n)
    up = find_paths(start_row - 1, start_col, k - 1, m, n)
    right = find_paths(start_row, start_col + 1, k - 1, m, n)
    left = find_paths(start_row, start_col - 1, k - 1, m, n)
 
    # Store and return the result
    dp[start_row][start_col][k] = ((down + up) % mod + right) % mod + left
    return dp[start_row][start_col][k]
 
# Driver code
m = 2
n = 2
k = 2
start_row = 0
start_col = 0
 
# Initialize the DP array with -1.
dp = [[[-1 for _ in range(k + 1)] for _ in range(n)] for _ in range(m)]
 
# Call the find_paths function with
# the given parameters.
print(find_paths(start_row, start_col, k, m, n))


C#




// C# program for the above approach
using System;
 
public class GFG {
    static long[, , ] dp;
    static int mod = 1000000007;
 
    static long FindPaths(int startRow, int startCol, int k,
                          int m, int n)
    {
        // Base cases
        if (startRow >= m || startRow < 0 || startCol >= n
            || startCol < 0)
            // We have moved out of the matrix,
            // one path found.
            return 1;
 
        if (k == 0)
            // All moves exhausted
            return 0;
 
        if (dp[startRow, startCol, k] != -1)
            // Return result if already calculated
            return dp[startRow, startCol, k];
 
        // Calculate the number of paths by recursively
        // exploring all four directions.
        long down = FindPaths(startRow + 1, startCol, k - 1,
                              m, n);
        long up = FindPaths(startRow - 1, startCol, k - 1,
                            m, n);
        long right = FindPaths(startRow, startCol + 1,
                               k - 1, m, n);
        long left = FindPaths(startRow, startCol - 1, k - 1,
                              m, n);
 
        // Store and return the result
        return dp[startRow, startCol, k]
            = (((down + up) % mod + right) % mod + left)
              % mod;
    }
 
    // Driver code
    public static void Main()
    {
        int m = 2, n = 2, k = 2, startRow = 0, startCol = 0;
 
        // Initialize the DP array with -1.
        dp = new long[m, n, k + 1];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                for (int l = 0; l <= k; l++) {
                    dp[i, j, l] = -1;
                }
            }
        }
 
        // Call the FindPaths function with the given
        // parameters.
        Console.WriteLine(
            FindPaths(startRow, startCol, k, m, n));
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// Javascript Code for the above approach:
let dp = new Array(52)
    .fill(null)
    .map(() =>
        new Array(52)
            .fill(null)
            .map(() => new Array(52).fill(-1))
    );
const mod = 1e9 + 7;
 
function findPaths(startRow, startCol, k, m, n) {
    // Base cases
    if (
        startRow >= m ||
        startRow < 0 ||
        startCol >= n ||
        startCol < 0
    ) {
        // We have moved out of the matrix,
        // one path found.
        return 1;
    }
 
    if (k === 0) {
        // All moves exhausted
        return 0;
    }
 
    if (dp[startRow][startCol][k] !== -1) {
        // Return result if already calculated
        return dp[startRow][startCol][k];
    }
 
    // Calculate the number of paths by recursively
    // exploring all four directions.
    let down = findPaths(startRow + 1, startCol, k - 1, m, n);
    let up = findPaths(startRow - 1, startCol, k - 1, m, n);
    let right = findPaths(startRow, startCol + 1, k - 1, m, n);
    let left = findPaths(startRow, startCol - 1, k - 1, m, n);
 
    // Store and return the result
    return (dp[startRow][startCol][k] =
        (((down + up) % mod + right) % mod + left) % mod);
}
 
// Driver code
function main() {
    let m = 2,
        n = 2,
        k = 2,
        startRow = 0,
        startColumn = 0;
 
    // Initialize the DP array with -1.
    for (let i = 0; i < 52; i++) {
        for (let j = 0; j < 52; j++) {
            for (let l = 0; l < 52; l++) {
                dp[i][j][l] = -1;
            }
        }
    }
 
    // Call the findPaths function with the given
    // parameters.
    console.log(findPaths(startRow, startColumn, k, m, n));
}
 
main();


Output

6






Time Complexity: O(M * N * K), where K, M, N are the maximum moves allowed, total rows and columns of matrix respectively.
Auxiliary Space: O(M * N * K)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads