Rat in a Maze with multiple steps or jump allowed

Last Updated : 26 May, 2026

Given a matrix mat[][] of size n × n, where mat[i][j] represents the maximum number of steps a rat can jump either forward (right) or downward from that cell, find a path for the rat to reach from the top-left cell (0, 0) to the bottom-right cell (n - 1, n - 1). A cell containing 0 is blocked and cannot be used in the path.

Return an n × n matrix where 1 represents the cells included in the path and 0 represents the remaining cells.

Note: If multiple valid paths exist, choose the path with the shortest possible jumps first. For the same jump length, moving forward (right) should be preferred over moving downward.

Examples:  

Input: mat[][] = [[2, 1, 0, 0],
[3, 0, 0, 1],
[0, 1, 0, 1],
[0, 0, 0, 1]]
Output: [[1, 0, 0, 0],
[1, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1]]
Explanation:
The rat starts from cell (0, 0) which contains value 2, so it can jump at most 2 steps either right or downward.
It first tries moving right to (0, 1), but this path does not lead to the destination.
The rat then moves downward to (1, 0) which contains value 3.
From this cell, it jumps 3 steps to the right and reaches (1, 3).
Since (1, 3) contains value 1, the rat can move downward one step at a time to (2, 3) and finally to (3, 3), which is the destination cell.

Input: mat[][] = [[2, 1, 0, 0],
[2, 0, 0, 1],
[0, 1, 0, 1],
[0, 0, 0, 1]]
Output: [[-1]]
Explanation:
The rat starts from cell (0, 0) which contains value 2, so it can jump at most 2 steps either right or downward.
However, every possible path eventually gets blocked by cells containing 0, making it impossible to reach the destination cell (3, 3).
Therefore, no valid path exists and the output is [[-1]].  

Try It Yourself
redirect icon

Using Recursion + Backtracking - O(2^(n^2)) Time and O(n^2) Space

The idea is to explore all possible paths from (0,0) to (n-1,n-1) using recursive traversal while ensuring each move stays within bounds, avoids blocked cells, and prevents revisiting. At each step, it prioritizes moving right first, then down, attempting all possible jumps allowed by the current cell. If a path reaches the destination, it returns the path matrix; otherwise, it backtracks and explores alternatives. If no valid path exists, it returns -1.

  • Recursively explore paths by making jumps in the right and downward directions.
  • Handle the base case: If the destination (n-1, n-1) is reached, mark the cell and return true.
  • Backtrack if a path fails by resetting the cell and trying the next possibility.
  • Generate the output matrix by storing the path taken in a separate 2D array and returning it if a valid path exists.
  • Handle the no solution case: If no path is found, return a matrix containing -1.
C++
// C++ program for Rat Maze With Multiple 
// Jumps using Recursion + Backtracking
#include <bits/stdc++.h>
using namespace std;

// Function to check if the cell is valid
bool isSafe(int row, int col, int n, 
            vector<vector<int>>& mat) {
    return (row >= 0 && row < n && col >= 0 && 
            col < n && mat[row][col] != 0);
}

// Recursive function to find the path
bool findPath(vector<vector<int>>& mat, 
              vector<vector<int>>& path, 
              int row, int col, int n) {
    
    // Base case: If destination is reached
    if (row == n - 1 && col == n - 1) {
        path[row][col] = 1;
        return true;
    }

    // Check if cell is valid and not visited
    if (isSafe(row, col, n, mat) && 
        !path[row][col]) {
        
        path[row][col] = 1; // Mark cell

        // Try moving right first
        for (int jump = 1; jump <= mat[row][col] 
                           && jump < n; jump++) {
            if (findPath(mat, path, row, col + jump, n)) 
                return true;
            if (findPath(mat, path, row + jump, col, n)) 
                return true;
        }

        path[row][col] = 0; // Backtrack
        return false;
    }
    return false;
}

// Function to get the shortest path matrix
vector<vector<int>> shortestDist(vector<vector<int>>& mat) {
    int n = mat.size();

    // Initialize path matrix
    vector<vector<int>> path(n, vector<int>(n, 0));

    // If no path exists, return -1
    if (!findPath(mat, path, 0, 0, n)) 
        return {{-1}};

    return path;
}

// Function to print 2D array
void print2dArray(vector<vector<int>>& arr) {
    for (auto& row : arr) {
        for (auto& cell : row) 
            cout << cell << " ";
        cout << endl;
    }
}

int main() {
 
    vector<vector<int>> mat = {
        {2, 1, 0, 0},
        {3, 0, 0, 1},
        {0, 1, 0, 1},
        {0, 0, 0, 1}
    };

    // Get shortest path matrix
    vector<vector<int>> result = 
        shortestDist(mat);

    print2dArray(result);

    return 0;
}
Java
// Java program for Rat Maze With Multiple Jumps
// using Recursion + Backtracking
import java.util.*;

class GfG {
    
    // Function to check if the cell is valid
    static boolean isSafe(int row, int col, int n, int[][] mat) {
        return (row >= 0 && row < n && col >= 0 && 
                col < n && mat[row][col] != 0);
    }
    
    // Recursive function to find the path
    static boolean findPath(int[][] mat, int[][] path, 
                            int row, int col, int n) {
        
        // Base case: If destination is reached
        if (row == n - 1 && col == n - 1) {
            path[row][col] = 1;
            return true;
        }
        
        // Check if cell is valid and not visited
        if (isSafe(row, col, n, mat) && 
            path[row][col] == 0) {
            
            path[row][col] = 1; // Mark cell
            
            // Try moving right first
            for (int jump = 1; jump <= mat[row][col] && jump < n; jump++) {
                if (col + jump < n && findPath(mat, path, row, col + jump, n)) 
                    return true;
                if (row + jump < n && findPath(mat, path, row + jump, col, n)) 
                    return true;
            }
            
            path[row][col] = 0; // Backtrack
            return false;
        }
        return false;
    }
    
    // Function to get the shortest path matrix
    static int[][] shortestDist(int[][] mat) {
        int n = mat.length;
        
        // Initialize path matrix
        int[][] path = new int[n][n];
        
        // If no path exists, return -1
        if (!findPath(mat, path, 0, 0, n)) 
            return new int[][]{{-1}};
        
        return path;
    }
    
    // Function to print 2D array
    static void print2dArray(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        int[][] mat = {
            {2, 1, 0, 0},
            {3, 0, 0, 1},
            {0, 1, 0, 1},
            {0, 0, 0, 1}
        };
        
        // Get shortest path matrix
        int[][] result = shortestDist(mat);
        
        print2dArray(result);
    }
}
Python
# Python program for Rat Maze With Multiple Jumps
# using Recursion + Backtracking

# Function to check if the cell is valid
def isSafe(row, col, n, mat):
    return (row >= 0 and row < n and col >= 0 and 
            col < n and mat[row][col] != 0)

# Recursive function to find the path
def findPath(mat, path, row, col, n):
    
    # Base case: If destination is reached
    if row == n - 1 and col == n - 1:
        path[row][col] = 1
        return True
    
    # Check if cell is valid and not visited
    if isSafe(row, col, n, mat) and not path[row][col]:
        
        path[row][col] = 1  # Mark cell
        
        # Try moving right first
        for jump in range(1, mat[row][col] + 1):
            if jump < n:
                if col + jump < n and findPath(mat, path, row, col + jump, n):
                    return True
                if row + jump < n and findPath(mat, path, row + jump, col, n):
                    return True
        
        path[row][col] = 0  # Backtrack
        return False
    return False

# Function to get the shortest path matrix
def shortestDist(mat):
    n = len(mat)
    
    # Initialize path matrix
    path = [[0] * n for _ in range(n)]
    
    # If no path exists, return -1
    if not findPath(mat, path, 0, 0, n):
        return [[-1]]
    
    return path

# Function to print 2D array
def print2dArray(arr):
    for row in arr:
        for cell in row:
            print(cell, end=" ")
        print()

# Main function
if __name__ == "__main__":
    mat = [
        [2, 1, 0, 0],
        [3, 0, 0, 1],
        [0, 1, 0, 1],
        [0, 0, 0, 1]
    ]
    
    # Get shortest path matrix
    result = shortestDist(mat)
    
    print2dArray(result)
C#
// C# program for Rat Maze With Multiple Jumps
// using Recursion + Backtracking
using System;

class GfG {
    
    // Function to check if the cell is valid
    static bool isSafe(int row, int col, int n, int[,] mat) {
        return (row >= 0 && row < n && col >= 0 && 
                col < n && mat[row, col] != 0);
    }
    
    // Recursive function to find the path
    static bool findPath(int[,] mat, int[,] path, 
                         int row, int col, int n) {
        
        // Base case: If destination is reached
        if (row == n - 1 && col == n - 1) {
            path[row, col] = 1;
            return true;
        }
        
        // Check if cell is valid and not visited
        if (isSafe(row, col, n, mat) && 
            path[row, col] == 0) {
            
            path[row, col] = 1; // Mark cell
            
            // Try moving right first
            for (int jump = 1; jump <= mat[row, col] && jump < n; jump++) {
                if (col + jump < n && findPath(mat, path, row, col + jump, n)) 
                    return true;
                if (row + jump < n && findPath(mat, path, row + jump, col, n)) 
                    return true;
            }
            
            path[row, col] = 0; // Backtrack
            return false;
        }
        return false;
    }
    
    // Function to get the shortest path matrix
    static int[,] shortestDist(int[,] mat) {
        int n = mat.GetLength(0);
        
        // Initialize path matrix
        int[,] path = new int[n, n];
        
        // If no path exists, return -1
        if (!findPath(mat, path, 0, 0, n)) 
            return new int[,] { { -1 } };
        
        return path;
    }
    
    // Function to print 2D array
    static void print2dArray(int[,] arr) {
        int rows = arr.GetLength(0);
        int cols = arr.GetLength(1);
        
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                Console.Write(arr[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
    
    static void Main(string[] args) {
        int[,] mat = {
            {2, 1, 0, 0},
            {3, 0, 0, 1},
            {0, 1, 0, 1},
            {0, 0, 0, 1}
        };
        
        // Get shortest path matrix
        int[,] result = shortestDist(mat);
        
        print2dArray(result);
    }
}
JavaScript
// JavaScript program for Rat Maze With Multiple Jumps
// using Recursion + Backtracking

// Function to check if the cell is valid
function isSafe(row, col, n, mat) {
    return (row >= 0 && row < n && col >= 0 && 
            col < n && mat[row][col] !== 0);
}

// Recursive function to find the path
function findPath(mat, path, row, col, n) {
    
    // Base case: If destination is reached
    if (row === n - 1 && col === n - 1) {
        path[row][col] = 1;
        return true;
    }
    
    // Check if cell is valid and not visited
    if (isSafe(row, col, n, mat) && 
        path[row][col] === 0) {
        
        path[row][col] = 1; // Mark cell
        
        // Try moving right first
        for (let jump = 1; jump <= mat[row][col] && jump < n; jump++) {
            if (col + jump < n && findPath(mat, path, row, col + jump, n)) 
                return true;
            if (row + jump < n && findPath(mat, path, row + jump, col, n)) 
                return true;
        }
        
        path[row][col] = 0; // Backtrack
        return false;
    }
    return false;
}

// Function to get the shortest path matrix
function shortestDist(mat) {
    const n = mat.length;
    
    // Initialize path matrix
    const path = Array(n).fill().map(() => Array(n).fill(0));
    
    // If no path exists, return -1
    if (!findPath(mat, path, 0, 0, n)) 
        return [[-1]];
    
    return path;
}

// Function to print 2D array
function print2dArray(arr) {
    for (let row of arr) {
        console.log(row.join(' '));
    }
}

// Main execution
const mat = [
    [2, 1, 0, 0],
    [3, 0, 0, 1],
    [0, 1, 0, 1],
    [0, 0, 0, 1]
];

// Get shortest path matrix
const result = shortestDist(mat);
print2dArray(result);

Output
1 0 0 0 
1 0 0 1 
0 0 0 1 
0 0 0 1 

[Efficient Approach] Finding Shortest Valid Path – O(n² × maxJump) Time and O(n²) Space

The idea is to use recursion and backtracking to find a valid path from the top-left cell to the bottom-right cell. From each cell, jumps from 1 to the cell value are tried first toward the right and then downward. Memoization is used to avoid recomputing already visited states, while backtracking helps mark and unmark the current path in the answer matrix.

  • Start recursion from cell (0,0)
  • Base cases: Out of bounds -> invalid. Blocked cell -> invalid. Destination reached -? valid path found
  • Mark current cell in answer matrix
  • Try all possible jumps: Move right first, then move downward
  • If no path works, backtrack by removing current cell from path
  • Use DP table to store previously computed results
C++
#include <bits/stdc++.h>
using namespace std;

bool solve(int i, int j, vector<vector<int>> &mat, vector<vector<int>> &ans, vector<vector<int>> &dp)
{

    int n = mat.size();

    // out of bounds
    if (i >= n || j >= n)
        return false;

    // destination
    if (i == n - 1 && j == n - 1)
    {
        ans[i][j] = 1;
        return true;
    }

    // blocked cell
    if (mat[i][j] == 0)
        return false;

    // memoization
    if (dp[i][j] != -1)
        return dp[i][j];

    ans[i][j] = 1;

    int jump = mat[i][j];

    // shortest jumps first
    for (int step = 1; step <= jump; step++)
    {

        // right first
        if (solve(i, j + step, mat, ans, dp))
        {
            return dp[i][j] = 1;
        }

        // down
        if (solve(i + step, j, mat, ans, dp))
        {
            return dp[i][j] = 1;
        }
    }

    ans[i][j] = 0;

    return dp[i][j] = 0;
}

vector<vector<int>> shortestDist(vector<vector<int>> &mat)
{

    int n = mat.size();

    // special case
    if (n == 1)
        return {{1}};

    vector<vector<int>> ans(n, vector<int>(n, 0));

    // blocked start
    if (mat[0][0] == 0)
        return {{-1}};

    vector<vector<int>> dp(n, vector<int>(n, -1));

    if (!solve(0, 0, mat, ans, dp))
        return {{-1}};

    return ans;
}

void print2dArray(vector<vector<int>> &arr)
{
    for (auto &row : arr)
    {
        for (auto &cell : row)
            cout << cell << " ";
        cout << endl;
    }
}

int main()
{

    vector<vector<int>> mat = {{2, 1, 0, 0}, {3, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 0, 1}};

    // Get shortest path matrix
    vector<vector<int>> result = shortestDist(mat);

    print2dArray(result);

    return 0;
}
Java
// Java program for Rat Maze With Multiple Jumps using Memoization
import java.util.*;

class GfG {
    
    static boolean solve(int i, int j, int[][] mat, int[][] ans, int[][] dp) {
        int n = mat.length;
        
        // out of bounds
        if (i >= n || j >= n)
            return false;
        
        // destination
        if (i == n - 1 && j == n - 1) {
            ans[i][j] = 1;
            return true;
        }
        
        // blocked cell
        if (mat[i][j] == 0)
            return false;
        
        // memoization
        if (dp[i][j] != -1)
            return dp[i][j] == 1;
        
        ans[i][j] = 1;
        
        int jump = mat[i][j];
        
        // shortest jumps first
        for (int step = 1; step <= jump; step++) {
            // right first
            if (j + step < n && solve(i, j + step, mat, ans, dp)) {
                dp[i][j] = 1;
                return true;
            }
            
            // down
            if (i + step < n && solve(i + step, j, mat, ans, dp)) {
                dp[i][j] = 1;
                return true;
            }
        }
        
        ans[i][j] = 0;
        dp[i][j] = 0;
        return false;
    }
    
    static int[][] shortestDist(int[][] mat) {
        int n = mat.length;
        
        // special case
        if (n == 1)
            return new int[][]{{1}};
        
        int[][] ans = new int[n][n];
        
        // blocked start
        if (mat[0][0] == 0)
            return new int[][]{{-1}};
        
        int[][] dp = new int[n][n];
        for (int i = 0; i < n; i++) {
            Arrays.fill(dp[i], -1);
        }
        
        if (!solve(0, 0, mat, ans, dp))
            return new int[][]{{-1}};
        
        return ans;
    }
    
    static void print2dArray(int[][] arr) {
        for (int[] row : arr) {
            for (int cell : row) {
                System.out.print(cell + " ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        int[][] mat = {
            {2, 1, 0, 0},
            {3, 0, 0, 1},
            {0, 1, 0, 1},
            {0, 0, 0, 1}
        };
        
        // Get shortest path matrix
        int[][] result = shortestDist(mat);
        
        print2dArray(result);
    }
}
Python
# Python program for Rat Maze With Multiple Jumps using Memoization

def solve(i, j, mat, ans, dp):
    n = len(mat)
    
    # out of bounds
    if i >= n or j >= n:
        return False
    
    # destination
    if i == n - 1 and j == n - 1:
        ans[i][j] = 1
        return True
    
    # blocked cell
    if mat[i][j] == 0:
        return False
    
    # memoization
    if dp[i][j] != -1:
        return dp[i][j] == 1
    
    ans[i][j] = 1
    
    jump = mat[i][j]
    
    # shortest jumps first
    for step in range(1, jump + 1):
        # right first
        if j + step < n and solve(i, j + step, mat, ans, dp):
            dp[i][j] = 1
            return True
        
        # down
        if i + step < n and solve(i + step, j, mat, ans, dp):
            dp[i][j] = 1
            return True
    
    ans[i][j] = 0
    dp[i][j] = 0
    return False

def shortestDist(mat):
    n = len(mat)
    
    # special case
    if n == 1:
        return [[1]]
    
    ans = [[0] * n for _ in range(n)]
    
    # blocked start
    if mat[0][0] == 0:
        return [[-1]]
    
    dp = [[-1] * n for _ in range(n)]
    
    if not solve(0, 0, mat, ans, dp):
        return [[-1]]
    
    return ans

def print2dArray(arr):
    for row in arr:
        print(' '.join(map(str, row)))

# Driver code
if __name__ == "__main__":
    mat = [
        [2, 1, 0, 0],
        [3, 0, 0, 1],
        [0, 1, 0, 1],
        [0, 0, 0, 1]
    ]
    
    # Get shortest path matrix
    result = shortestDist(mat)
    
    print2dArray(result)
C#
// C# program for Rat Maze With Multiple Jumps using Memoization
using System;

class GfG {
    
    static bool solve(int i, int j, int[][] mat, int[][] ans, int[][] dp) {
        int n = mat.Length;
        
        // out of bounds
        if (i >= n || j >= n)
            return false;
        
        // destination
        if (i == n - 1 && j == n - 1) {
            ans[i][j] = 1;
            return true;
        }
        
        // blocked cell
        if (mat[i][j] == 0)
            return false;
        
        // memoization
        if (dp[i][j] != -1)
            return dp[i][j] == 1;
        
        ans[i][j] = 1;
        
        int jump = mat[i][j];
        
        // shortest jumps first
        for (int step = 1; step <= jump; step++) {
            // right first
            if (j + step < n && solve(i, j + step, mat, ans, dp)) {
                dp[i][j] = 1;
                return true;
            }
            
            // down
            if (i + step < n && solve(i + step, j, mat, ans, dp)) {
                dp[i][j] = 1;
                return true;
            }
        }
        
        ans[i][j] = 0;
        dp[i][j] = 0;
        return false;
    }
    
    static int[][] shortestDist(int[][] mat) {
        int n = mat.Length;
        
        // special case
        if (n == 1)
            return new int[][] { new int[] { 1 } };
        
        int[][] ans = new int[n][];
        for (int i = 0; i < n; i++) {
            ans[i] = new int[n];
        }
        
        // blocked start
        if (mat[0][0] == 0)
            return new int[][] { new int[] { -1 } };
        
        int[][] dp = new int[n][];
        for (int i = 0; i < n; i++) {
            dp[i] = new int[n];
            for (int j = 0; j < n; j++) {
                dp[i][j] = -1;
            }
        }
        
        if (!solve(0, 0, mat, ans, dp))
            return new int[][] { new int[] { -1 } };
        
        return ans;
    }
    
    static void print2dArray(int[][] arr) {
        foreach (var row in arr) {
            foreach (var cell in row) {
                Console.Write(cell + " ");
            }
            Console.WriteLine();
        }
    }
    
    static void Main(string[] args) {
        int[][] mat = new int[][] {
            new int[] { 2, 1, 0, 0 },
            new int[] { 3, 0, 0, 1 },
            new int[] { 0, 1, 0, 1 },
            new int[] { 0, 0, 0, 1 }
        };
        
        // Get shortest path matrix
        int[][] result = shortestDist(mat);
        
        print2dArray(result);
    }
}
JavaScript
// JavaScript program for Rat Maze With Multiple Jumps using Memoization

function solve(i, j, mat, ans, dp) {
    const n = mat.length;
    
    // out of bounds
    if (i >= n || j >= n)
        return false;
    
    // destination
    if (i === n - 1 && j === n - 1) {
        ans[i][j] = 1;
        return true;
    }
    
    // blocked cell
    if (mat[i][j] === 0)
        return false;
    
    // memoization
    if (dp[i][j] !== -1)
        return dp[i][j] === 1;
    
    ans[i][j] = 1;
    
    const jump = mat[i][j];
    
    // shortest jumps first
    for (let step = 1; step <= jump; step++) {
        // right first
        if (j + step < n && solve(i, j + step, mat, ans, dp)) {
            dp[i][j] = 1;
            return true;
        }
        
        // down
        if (i + step < n && solve(i + step, j, mat, ans, dp)) {
            dp[i][j] = 1;
            return true;
        }
    }
    
    ans[i][j] = 0;
    dp[i][j] = 0;
    return false;
}

function shortestDist(mat) {
    const n = mat.length;
    
    // special case
    if (n === 1)
        return [[1]];
    
    const ans = Array(n).fill().map(() => Array(n).fill(0));
    
    // blocked start
    if (mat[0][0] === 0)
        return [[-1]];
    
    const dp = Array(n).fill().map(() => Array(n).fill(-1));
    
    if (!solve(0, 0, mat, ans, dp))
        return [[-1]];
    
    return ans;
}

function print2dArray(arr) {
    for (const row of arr) {
        console.log(row.join(' '));
    }
}

// Driver code
const mat = [
    [2, 1, 0, 0],
    [3, 0, 0, 1],
    [0, 1, 0, 1],
    [0, 0, 0, 1]
];

// Get shortest path matrix
const result = shortestDist(mat);

print2dArray(result);

Output
1 0 0 0 
1 0 0 1 
0 0 0 1 
0 0 0 1 


Comment