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. It is guaranteed that the cell mat[n-1][n-1] is not 0.
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.
The rat starts from cell (0, 0) which contains value 2, so it can jump at most 2 steps either right or downward.
Steps:
-> Moves downward to (1, 0) which contains value 3.
-> Jumps 3 steps right to reach (1, 3).
-> Moves downward through (2, 3) and reaches the destination cell (3, 3).
Input: mat[][] = [[2, 1, 0, 0], [2, 0, 0, 1], [0, 1, 0, 1], [0, 0, 0, 1]] Output: [[-1]] Explanation: The rat starts at (0, 0) with value 2, but every possible path from there eventually reaches a cell containing 0. Since no sequence of jumps can reach the destination cell (3, 3), no valid path exists and the output is [[-1]].
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++
#include<bits/stdc++.h>usingnamespacestd;// Function to check if the cell is validboolisSafe(introw,intcol,intn,vector<vector<int>>&mat){return(row>=0&&row<n&&col>=0&&col<n&&mat[row][col]!=0);}// Recursive function to find the pathboolfindPath(vector<vector<int>>&mat,vector<vector<int>>&path,introw,intcol,intn){// Base case: If destination is reachedif(row==n-1&&col==n-1){path[row][col]=1;returntrue;}// Check if cell is valid and not visitedif(isSafe(row,col,n,mat)&&!path[row][col]){// Mark cellpath[row][col]=1;// Try moving right firstfor(intjump=1;jump<=mat[row][col]&&jump<n;jump++){if(findPath(mat,path,row,col+jump,n))returntrue;if(findPath(mat,path,row+jump,col,n))returntrue;}// Backtrackpath[row][col]=0;returnfalse;}returnfalse;}// Function to get the shortest path matrixvector<vector<int>>shortestDist(vector<vector<int>>&mat){intn=mat.size();// Initialize path matrixvector<vector<int>>path(n,vector<int>(n,0));// If no path exists, return -1if(!findPath(mat,path,0,0,n))return{{-1}};returnpath;}// Function to print 2D arrayvoidprint2dArray(vector<vector<int>>&arr){for(auto&row:arr){for(auto&cell:row)cout<<cell<<" ";cout<<endl;}}intmain(){vector<vector<int>>mat={{2,1,0,0},{3,0,0,1},{0,1,0,1},{0,0,0,1}};// Get shortest path matrixvector<vector<int>>result=shortestDist(mat);print2dArray(result);return0;}
Java
importjava.util.*;classGfG{// Function to check if the cell is validstaticbooleanisSafe(introw,intcol,intn,int[][]mat){return(row>=0&&row<n&&col>=0&&col<n&&mat[row][col]!=0);}staticbooleanfindPath(int[][]mat,ArrayList<ArrayList<Integer>>path,introw,intcol,intn){// Base case: If destination is reachedif(row==n-1&&col==n-1){path.get(row).set(col,1);returntrue;}// Check if cell is valid and not visited (equals 0)if(isSafe(row,col,n,mat)&&path.get(row).get(col)==0){// Mark cellpath.get(row).set(col,1);// Try moving right firstfor(intjump=1;jump<=mat[row][col]&&jump<n;jump++){if(col+jump<n&&findPath(mat,path,row,col+jump,n))returntrue;if(row+jump<n&&findPath(mat,path,row+jump,col,n))returntrue;}// Backtrackpath.get(row).set(col,0);returnfalse;}returnfalse;}// Function to get the shortest path matrixstaticArrayList<ArrayList<Integer>>shortestDist(int[][]mat){intn=mat.length;ArrayList<ArrayList<Integer>>path=newArrayList<>();for(inti=0;i<n;i++){ArrayList<Integer>row=newArrayList<>(Collections.nCopies(n,0));path.add(row);}// Call the helper function// If no path exists, return [[-1]]if(!findPath(mat,path,0,0,n)){ArrayList<ArrayList<Integer>>noPath=newArrayList<>();ArrayList<Integer>row=newArrayList<>();row.add(-1);noPath.add(row);returnnoPath;}returnpath;}// Function to print 2D ArrayListstaticvoidprint2dArray(ArrayList<ArrayList<Integer>>arr){for(inti=0;i<arr.size();i++){for(intj=0;j<arr.get(i).size();j++){System.out.print(arr.get(i).get(j)+" ");}System.out.println();}}publicstaticvoidmain(String[]args){int[][]mat={{2,1,0,0},{3,0,0,1},{0,1,0,1},{0,0,0,1}};// Get shortest path matrixArrayList<ArrayList<Integer>>result=shortestDist(mat);print2dArray(result);}}
Python
# Function to check if the cell is validdefisSafe(row,col,n,mat):return(row>=0androw<nandcol>=0andcol<nandmat[row][col]!=0)# Recursive function to find the pathdeffindPath(mat,path,row,col,n):# Base case: If destination is reachedifrow==n-1andcol==n-1:path[row][col]=1returnTrue# Check if cell is valid and not visitedifisSafe(row,col,n,mat)andnotpath[row][col]:# Mark cellpath[row][col]=1# Try moving right firstforjumpinrange(1,mat[row][col]+1):ifjump<n:ifcol+jump<nandfindPath(mat,path,row,col+jump,n):returnTrueifrow+jump<nandfindPath(mat,path,row+jump,col,n):returnTrue# Backtrackpath[row][col]=0returnFalsereturnFalse# Function to get the shortest path matrixdefshortestDist(mat):n=len(mat)# Initialize path matrixpath=[[0]*nfor_inrange(n)]# If no path exists, return -1ifnotfindPath(mat,path,0,0,n):return[[-1]]returnpath# Function to print 2D arraydefprint2dArray(arr):forrowinarr:forcellinrow:print(cell,end=" ")print()# Main functionif__name__=="__main__":mat=[[2,1,0,0],[3,0,0,1],[0,1,0,1],[0,0,0,1]]# Get shortest path matrixresult=shortestDist(mat)print2dArray(result)
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// Function to check if the cell is validstaticboolisSafe(introw,intcol,intn,int[,]mat){return(row>=0&&row<n&&col>=0&&col<n&&mat[row,col]!=0);}staticboolfindPath(int[,]mat,List<List<int>>path,introw,intcol,intn){// Base case: If destination is reachedif(row==n-1&&col==n-1){path[row][col]=1;returntrue;}// Check if cell is valid and not visitedif(isSafe(row,col,n,mat)&&path[row][col]==0){// Mark cellpath[row][col]=1;// Try moving right firstfor(intjump=1;jump<=mat[row,col]&&jump<n;jump++){if(col+jump<n&&findPath(mat,path,row,col+jump,n))returntrue;if(row+jump<n&&findPath(mat,path,row+jump,col,n))returntrue;}// Backtrackpath[row][col]=0;returnfalse;}returnfalse;}// Function to get the shortest path matrixpublicstaticList<List<int>>shortestDist(int[,]mat){intn=mat.GetLength(0);// Initialize path List of Lists with all 0sList<List<int>>path=newList<List<int>>();for(inti=0;i<n;i++){List<int>row=newList<int>();for(intj=0;j<n;j++){row.Add(0);}path.Add(row);}// If no path exists, return [[-1]]if(!findPath(mat,path,0,0,n)){returnnewList<List<int>>{newList<int>{-1}};}returnpath;}// Function to print 2D Liststaticvoidprint2dList(List<List<int>>arr){for(inti=0;i<arr.Count;i++){for(intj=0;j<arr[i].Count;j++){Console.Write(arr[i][j]+" ");}Console.WriteLine();}}staticvoidMain(string[]args){int[,]mat=newint[,]{{2,1,0,0},{3,0,0,1},{0,1,0,1},{0,0,0,1}};// Get shortest path matrixList<List<int>>result=shortestDist(mat);print2dList(result);}}
JavaScript
// Function to check if the cell is validfunctionisSafe(row,col,n,mat){return(row>=0&&row<n&&col>=0&&col<n&&mat[row][col]!==0);}// Recursive function to find the pathfunctionfindPath(mat,path,row,col,n){// Base case: If destination is reachedif(row===n-1&&col===n-1){path[row][col]=1;returntrue;}// Check if cell is valid and not visitedif(isSafe(row,col,n,mat)&&path[row][col]===0){// Mark cellpath[row][col]=1;// Try moving right firstfor(letjump=1;jump<=mat[row][col]&&jump<n;jump++){if(col+jump<n&&findPath(mat,path,row,col+jump,n))returntrue;if(row+jump<n&&findPath(mat,path,row+jump,col,n))returntrue;}// Backtrackpath[row][col]=0;returnfalse;}returnfalse;}// Function to get the shortest path matrixfunctionshortestDist(mat){constn=mat.length;// Initialize path matrixconstpath=Array(n).fill().map(()=>Array(n).fill(0));// If no path exists, return -1if(!findPath(mat,path,0,0,n))return[[-1]];returnpath;}// Function to print 2D arrayfunctionprint2dArray(arr){for(letrowofarr){console.log(row.join(' '));}}// Main executionconstmat=[[2,1,0,0],[3,0,0,1],[0,1,0,1],[0,0,0,1]];// Get shortest path matrixconstresult=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>usingnamespacestd;// Helper function to find path using DFS and Memoizationboolsolve(inti,intj,vector<vector<int>>&mat,vector<vector<int>>&ans,vector<vector<int>>&dp){intn=mat.size();// Out of boundsif(i>=n||j>=n)returnfalse;// Destination reachedif(i==n-1&&j==n-1){// Mark destination in pathans[i][j]=1;returntrue;}// Check if current cell is a blocked cellif(mat[i][j]==0)returnfalse;// Memoization: if already calculated, return stored resultif(dp[i][j]!=-1)returndp[i][j];// Mark current cell as part of the answer pathans[i][j]=1;intjump=mat[i][j];// Shortest jumps first (try 1 step, then 2 steps, etc.)for(intstep=1;step<=jump;step++){// Try moving right firstif(solve(i,j+step,mat,ans,dp)){returndp[i][j]=1;}// Try moving down if moving right failsif(solve(i+step,j,mat,ans,dp)){returndp[i][j]=1;}}// Backtrack: unmark cell if it leads to a dead endans[i][j]=0;returndp[i][j]=0;}// Function to set up and start finding the shortest distance pathvector<vector<int>>shortestDist(vector<vector<int>>&mat){intn=mat.size();// Special case: 1x1 matrixif(n==1)return{{1}};// Path matrix initialized to 0vector<vector<int>>ans(n,vector<int>(n,0));// Blocked start cell checkif(mat[0][0]==0)return{{-1}};// Memoization table initialized to -1 (unvisited state)vector<vector<int>>dp(n,vector<int>(n,-1));// Start DFS from (0, 0), return [[-1]] if no path foundif(!solve(0,0,mat,ans,dp))return{{-1}};returnans;}voidprint2dArray(vector<vector<int>>&arr){for(auto&row:arr){for(auto&cell:row)cout<<cell<<" ";cout<<endl;}}intmain(){vector<vector<int>>mat={{2,1,0,0},{3,0,0,1},{0,1,0,1},{0,0,0,1}};// Get shortest path matrixvector<vector<int>>result=shortestDist(mat);print2dArray(result);return0;}
Java
importjava.util.*;classSolution{// Recursive helper function to find the pathbooleansolve(inti,intj,int[][]mat,ArrayList<ArrayList<Integer>>ans,int[][]dp){intn=mat.length;// Out of boundsif(i>=n||j>=n)returnfalse;// Destination reachedif(i==n-1&&j==n-1){ans.get(i).set(j,1);returntrue;}if(mat[i][j]==0)returnfalse;// Check memoization table if(dp[i][j]!=-1)returndp[i][j]==1;// Mark current cell as part of the pathans.get(i).set(j,1);intjump=mat[i][j];// Try all possible jumps for(intstep=1;step<=jump;step++){// Try moving right firstif(j+step<n&&solve(i,j+step,mat,ans,dp)){dp[i][j]=1;returntrue;}// Try moving down if(i+step<n&&solve(i+step,j,mat,ans,dp)){dp[i][j]=1;returntrue;}}// If no valid path found from this cell, unmark itans.get(i).set(j,0);dp[i][j]=0;returnfalse;}// Function to get the shortest path matrixpublicArrayList<ArrayList<Integer>>shortestDist(int[][]mat){intn=mat.length;ArrayList<ArrayList<Integer>>ans=newArrayList<>();for(inti=0;i<n;i++){ans.add(newArrayList<>(Collections.nCopies(n,0)));}if(n==1){ans.get(0).set(0,1);returnans;}if(mat[0][0]==0){ans.clear();ans.add(newArrayList<>(Arrays.asList(-1)));returnans;}// Initialize DP table with -1int[][]dp=newint[n][n];for(int[]row:dp){Arrays.fill(row,-1);}// Call the helper. If no path is found, return [[-1]]if(!solve(0,0,mat,ans,dp)){ans.clear();ans.add(newArrayList<>(Arrays.asList(-1)));returnans;}returnans;}}
Python
classSolution:defsolve(self,i,j,mat,ans,dp):n=len(mat)# Out of bounds checkifi>=norj>=n:returnFalse# Destination reachedifi==n-1andj==n-1:ans[i][j]=1returnTrue# Blocked cell checkifmat[i][j]==0:returnFalse# Return memoized resultifdp[i][j]!=-1:returndp[i][j]==1ans[i][j]=1jump=mat[i][j]# Try shorter jumps firstforstepinrange(1,jump+1):# Jump rightifj+step<nandself.solve(i,j+step,mat,ans,dp):dp[i][j]=1returnTrue# Jump downifi+step<nandself.solve(i+step,j,mat,ans,dp):dp[i][j]=1returnTrue# Backtrack if no path foundans[i][j]=0dp[i][j]=0returnFalsedefshortestDist(self,mat):n=len(mat)# Special case for 1x1 gridifn==1:return[[1]]ans=[[0]*nfor_inrange(n)]# Start cell is blockedifmat[0][0]==0:return[[-1]]dp=[[-1]*nfor_inrange(n)]# Return [[-1]] if no path existsifnotself.solve(0,0,mat,ans,dp):return[[-1]]returnans
C#
usingSystem;usingSystem.Collections.Generic;classGfG{staticboolsolve(inti,intj,int[,]mat,List<List<int>>ans,int[,]dp){intn=mat.GetLength(0);// Out of boundsif(i>=n||j>=n)returnfalse;// Destinationif(i==n-1&&j==n-1){ans[i][j]=1;returntrue;}// Blocked cellif(mat[i,j]==0)returnfalse;// Memoizationif(dp[i,j]!=-1)returndp[i,j]==1;ans[i][j]=1;intjump=mat[i,j];// Shortest jumps firstfor(intstep=1;step<=jump;step++){// Right firstif(j+step<n&&solve(i,j+step,mat,ans,dp)){dp[i,j]=1;returntrue;}// Downif(i+step<n&&solve(i+step,j,mat,ans,dp)){dp[i,j]=1;returntrue;}}ans[i][j]=0;dp[i,j]=0;returnfalse;}staticList<List<int>>shortestDist(int[,]mat){intn=mat.GetLength(0);List<List<int>>ans=newList<List<int>>();for(inti=0;i<n;i++){List<int>row=newList<int>();for(intj=0;j<n;j++){row.Add(0);}ans.Add(row);}// Special case matrix size 1if(n==1){ans[0][0]=1;returnans;}// Blocked startif(mat[0,0]==0)returnnewList<List<int>>{newList<int>{-1}};int[,]dp=newint[n,n];for(inti=0;i<n;i++){for(intj=0;j<n;j++){dp[i,j]=-1;}}// Call the helper. If no path is found, return [[-1]]if(!solve(0,0,mat,ans,dp))returnnewList<List<int>>{newList<int>{-1}};returnans;}staticvoidprint2dArray(List<List<int>>arr){foreach(varrowinarr){foreach(varcellinrow){Console.Write(cell+" ");}Console.WriteLine();}}staticvoidMain(string[]args){int[,]mat=newint[,]{{2,1,0,0},{3,0,0,1},{0,1,0,1},{0,0,0,1}};// Get shortest path matrixList<List<int>>result=shortestDist(mat);print2dArray(result);}}
JavaScript
functionsolve(i,j,mat,ans,dp){constn=mat.length;// out of boundsif(i>=n||j>=n)returnfalse;// destinationif(i===n-1&&j===n-1){ans[i][j]=1;returntrue;}// blocked cellif(mat[i][j]===0)returnfalse;// memoizationif(dp[i][j]!==-1)returndp[i][j]===1;ans[i][j]=1;constjump=mat[i][j];// shortest jumps firstfor(letstep=1;step<=jump;step++){// right firstif(j+step<n&&solve(i,j+step,mat,ans,dp)){dp[i][j]=1;returntrue;}// downif(i+step<n&&solve(i+step,j,mat,ans,dp)){dp[i][j]=1;returntrue;}}ans[i][j]=0;dp[i][j]=0;returnfalse;}functionshortestDist(mat){constn=mat.length;// special caseif(n===1)return[[1]];constans=Array(n).fill().map(()=>Array(n).fill(0));// blocked startif(mat[0][0]===0)return[[-1]];constdp=Array(n).fill().map(()=>Array(n).fill(-1));if(!solve(0,0,mat,ans,dp))return[[-1]];returnans;}functionprint2dArray(arr){for(constrowofarr){console.log(row.join(' '));}}// Driver codeconstmat=[[2,1,0,0],[3,0,0,1],[0,1,0,1],[0,0,0,1]];// Get shortest path matrixconstresult=shortestDist(mat);print2dArray(result);