Given a 2D binary matrix mat[][] where 0 represent hurdle and 1 free cell. Find the length of the longest path from a source (xs, ys) to a destination (xd, yd) with these rules:
Move only up, down, left, or right (no diagonals).
Each cell can be visited at most once in a path.
If reaching the destination is impossible, return -1.
[Approach] Using Backtracking with Visited Matrix - O(4(m*n)) Time and O(m*n) Space
The idea is to use backtracking. We start from the source cell and recursively explore all four allowed directions—up, down, left, and right while keeping track of the cells already visited using a visited array. For each move, we mark the current cell as visited and continue exploring valid adjacent cells. If we reach the destination, we update the length of the longest path found so far. After exploring a path, we backtrack by unmarking the cell in the visited array so it can be used in other paths.
C++
//Driver Code Starts#include<iostream>#include<vector>#include<climits>#include<algorithm>usingnamespacestd;//Driver Code Ends// Function to find the longest path using backtrackingintdfs(vector<vector<int>>&mat,vector<vector<bool>>&visited,inti,intj,intx,inty){intm=mat.size();intn=mat[0].size();// If destination is reachedif(i==x&&j==y){return0;}// If cell is invalid, blocked, or already visitedif(i<0||i>=m||j<0||j>=n||mat[i][j]==0||visited[i][j]){return-1;}// Mark current cell as visitedvisited[i][j]=true;intmaxPath=-1;// Four possible moves: up, down, left, rightintrow[]={-1,1,0,0};intcol[]={0,0,-1,1};for(intk=0;k<4;k++){intni=i+row[k];intnj=j+col[k];intpathLength=dfs(mat,visited,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!=-1){maxPath=max(maxPath,1+pathLength);}}// Backtrack - unmark current cellvisited[i][j]=false;returnmaxPath;}intlongestPath(vector<vector<int>>&mat,intxs,intys,intxd,intyd){intm=mat.size();intn=mat[0].size();// Check if source or destination is blockedif(mat[xs][ys]==0||mat[xd][yd]==0){return-1;}vector<vector<bool>>visited(m,vector<bool>(n,false));returndfs(mat,visited,xs,ys,xd,yd);}//Driver Code Startsintmain(){vector<vector<int>>mat={{1,1,1,1,1,1,1,1,1,1},{1,1,0,1,1,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};intxs=0,ys=0;intxd=1,yd=7;intresult=longestPath(mat,xs,ys,xd,yd);if(result!=-1)cout<<result<<endl;elsecout<<-1<<endl;return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.Arrays;classGFG{//Driver Code Ends// Function to find the longest path using backtrackingstaticintdfs(int[][]mat,boolean[][]visited,inti,intj,intx,inty){intm=mat.length;intn=mat[0].length;// If destination is reachedif(i==x&&j==y){return0;}// If cell is invalid, blocked, or already visitedif(i<0||i>=m||j<0||j>=n||mat[i][j]==0||visited[i][j]){return-1;// Invalid path}// Mark current cell as visitedvisited[i][j]=true;intmaxPath=-1;// Four possible moves: up, down, left, rightint[]row={-1,1,0,0};int[]col={0,0,-1,1};for(intk=0;k<4;k++){intni=i+row[k];intnj=j+col[k];intpathLength=dfs(mat,visited,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!=-1){maxPath=Math.max(maxPath,1+pathLength);}}// Backtrack - unmark current cellvisited[i][j]=false;returnmaxPath;}staticintlongestPath(int[][]mat,intxs,intys,intxd,intyd){intm=mat.length;intn=mat[0].length;// Check if source or destination is blockedif(mat[xs][ys]==0||mat[xd][yd]==0){return-1;}boolean[][]visited=newboolean[m][n];returndfs(mat,visited,xs,ys,xd,yd);}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]mat={{1,1,1,1,1,1,1,1,1,1},{1,1,0,1,1,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};intxs=0,ys=0;intxd=1,yd=7;intresult=longestPath(mat,xs,ys,xd,yd);if(result!=-1)System.out.println(result);elseSystem.out.println(-1);}}//Driver Code Ends
Python
# Function to find the longest path using backtrackingdefdfs(mat,visited,i,j,x,y):m=len(mat)n=len(mat[0])# If destination is reachedifi==xandj==y:return0# If cell is invalid, blocked, or already visitedifi<0ori>=morj<0orj>=normat[i][j]==0orvisited[i][j]:return-1# Invalid path# Mark current cell as visitedvisited[i][j]=TruemaxPath=-1# Four possible moves: up, down, left, rightrow=[-1,1,0,0]col=[0,0,-1,1]forkinrange(4):ni=i+row[k]nj=j+col[k]pathLength=dfs(mat,visited,ni,nj,x,y)# If a valid path is found from this directionifpathLength!=-1:maxPath=max(maxPath,1+pathLength)# Backtrack - unmark current cellvisited[i][j]=FalsereturnmaxPathdeflongestPath(mat,xs,ys,xd,yd):m=len(mat)n=len(mat[0])# Check if source or destination is blockedifmat[xs][ys]==0ormat[xd][yd]==0:return-1visited=[[Falsefor_inrange(n)]for_inrange(m)]returndfs(mat,visited,xs,ys,xd,yd)#Driver Code Startsif__name__=="__main__":mat=[[1,1,1,1,1,1,1,1,1,1],[1,1,0,1,1,0,1,1,0,1],[1,1,1,1,1,1,1,1,1,1]]xs,ys=0,0xd,yd=1,7result=longestPath(mat,xs,ys,xd,yd)ifresult!=-1:print(result)else:print(-1)#Driver Code Ends
C#
//Driver Code StartsusingSystem;classGFG{//Driver Code Ends// Function to find the longest path using backtrackingstaticintdfs(int[,]mat,bool[,]visited,inti,intj,intx,inty){intm=mat.GetLength(0);intn=mat.GetLength(1);// If destination is reachedif(i==x&&j==y){return0;}// If cell is invalid, blocked, or already visitedif(i<0||i>=m||j<0||j>=n||mat[i,j]==0||visited[i,j]){return-1;// Invalid path}// Mark current cell as visitedvisited[i,j]=true;intmaxPath=-1;// Four possible moves: up, down, left, rightint[]row={-1,1,0,0};int[]col={0,0,-1,1};for(intk=0;k<4;k++){intni=i+row[k];intnj=j+col[k];intpathLength=dfs(mat,visited,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!=-1){maxPath=Math.Max(maxPath,1+pathLength);}}// Backtrack - unmark current cellvisited[i,j]=false;returnmaxPath;}staticintlongestPath(int[,]mat,intxs,intys,intxd,intyd){intm=mat.GetLength(0);intn=mat.GetLength(1);// Check if source or destination is blockedif(mat[xs,ys]==0||mat[xd,yd]==0){return-1;}bool[,]visited=newbool[m,n];returndfs(mat,visited,xs,ys,xd,yd);}//Driver Code StartsstaticvoidMain(){int[,]mat={{1,1,1,1,1,1,1,1,1,1},{1,1,0,1,1,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};intxs=0,ys=0;intxd=1,yd=7;intresult=longestPath(mat,xs,ys,xd,yd);if(result!=-1)Console.WriteLine(result);elseConsole.WriteLine(-1);}}//Driver Code Ends
JavaScript
// Function to find the longest path using backtrackingfunctiondfs(mat,visited,i,j,x,y){constm=mat.length;constn=mat[0].length;// If destination is reachedif(i===x&&j===y){return0;}// If cell is invalid, blocked, or already visitedif(i<0||i>=m||j<0||j>=n||mat[i][j]===0||visited[i][j]){return-1;}// Mark current cell as visitedvisited[i][j]=true;letmaxPath=-1;// Four possible moves: up, down, left, rightconstrow=[-1,1,0,0];constcol=[0,0,-1,1];for(letk=0;k<4;k++){constni=i+row[k];constnj=j+col[k];constpathLength=dfs(mat,visited,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!==-1){maxPath=Math.max(maxPath,1+pathLength);}}// Backtrack - unmark current cellvisited[i][j]=false;returnmaxPath;}functionlongestPath(mat,xs,ys,xd,yd){constm=mat.length;constn=mat[0].length;// Check if source or destination is blockedif(mat[xs][ys]===0||mat[xd][yd]===0){return-1;}constvisited=Array(m).fill().map(()=>Array(n).fill(false));returndfs(mat,visited,xs,ys,xd,yd);}//Driver Code Starts// Driver Codeconstmat=[[1,1,1,1,1,1,1,1,1,1],[1,1,0,1,1,0,1,1,0,1],[1,1,1,1,1,1,1,1,1,1]];constxs=0,ys=0;constxd=1,yd=7;constresult=longestPath(mat,xs,ys,xd,yd);if(result!==-1)console.log(result);elseconsole.log(-1);//Driver Code Ends
Output
24
[Optimized Approach] Without Using Extra Space - O(4(m*n)) Time and O(1) Space
Instead of using a separate visited matrix, mark cells as visited directly in the input matrix by setting them to 0. Explore all four directions recursively. After finishing a path from a cell, restore its value to 1 (backtracking).
C++
//Driver Code Starts#include<iostream>#include<vector>#include<climits>#include<algorithm>usingnamespacestd;//Driver Code Ends// Function to find the longest path using backtracking without extra spaceintdfs(vector<vector<int>>&mat,inti,intj,intx,inty){intm=mat.size();intn=mat[0].size();// If destination is reachedif(i==x&&j==y){return0;}// If cell is invalid or blocked (0 means blocked or visited)if(i<0||i>=m||j<0||j>=n||mat[i][j]==0){return-1;}// Mark current cell as visited by temporarily setting it to 0mat[i][j]=0;intmaxPath=-1;// Four possible moves: up, down, left, rightintrow[]={-1,1,0,0};intcol[]={0,0,-1,1};for(intk=0;k<4;k++){intni=i+row[k];intnj=j+col[k];intpathLength=dfs(mat,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!=-1){maxPath=max(maxPath,1+pathLength);}}// Backtrack - restore the cell's original value (1)mat[i][j]=1;returnmaxPath;}intlongestPath(vector<vector<int>>&mat,intxs,intys,intxd,intyd){intm=mat.size();intn=mat[0].size();// Check if source or destination is blockedif(mat[xs][ys]==0||mat[xd][yd]==0){return-1;}returndfs(mat,xs,ys,xd,yd);}//Driver Code Startsintmain(){vector<vector<int>>mat={{1,1,1,1,1,1,1,1,1,1},{1,1,0,1,1,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};intxs=0,ys=0;intxd=1,yd=7;intresult=longestPath(mat,xs,ys,xd,yd);if(result!=-1)cout<<result<<endl;elsecout<<-1<<endl;return0;}//Driver Code Ends
Java
//Driver Code StartsclassGFG{//Driver Code Ends// Function to find the longest path using// backtracking without extra spacestaticintdfs(int[][]mat,inti,intj,intx,inty){intm=mat.length;intn=mat[0].length;// If destination is reachedif(i==x&&j==y){return0;}// If cell is invalid or blocked (0 means blocked or visited)if(i<0||i>=m||j<0||j>=n||mat[i][j]==0){return-1;}// Mark current cell as visited by temporarily setting it to 0mat[i][j]=0;intmaxPath=-1;// Four possible moves: up, down, left, rightint[]row={-1,1,0,0};int[]col={0,0,-1,1};for(intk=0;k<4;k++){intni=i+row[k];intnj=j+col[k];intpathLength=dfs(mat,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!=-1){maxPath=Math.max(maxPath,1+pathLength);}}// Backtrack - restore the cell's original value (1)mat[i][j]=1;returnmaxPath;}staticintlongestPath(int[][]mat,intxs,intys,intxd,intyd){intm=mat.length;intn=mat[0].length;// Check if source or destination is blockedif(mat[xs][ys]==0||mat[xd][yd]==0){return-1;}returndfs(mat,xs,ys,xd,yd);}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]mat={{1,1,1,1,1,1,1,1,1,1},{1,1,0,1,1,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};intxs=0,ys=0;intxd=1,yd=7;intresult=longestPath(mat,xs,ys,xd,yd);if(result!=-1)System.out.println(result);elseSystem.out.println(-1);}}//Driver Code Ends
Python
# Function to find the longest path # using backtracking without extra spacedefdfs(mat,i,j,x,y):m=len(mat)n=len(mat[0])# If destination is reachedifi==xandj==y:return0# If cell is invalid or blocked (0 means blocked or visited)ifi<0ori>=morj<0orj>=normat[i][j]==0:return-1# Mark current cell as visited by temporarily setting it to 0mat[i][j]=0maxPath=-1# Four possible moves: up, down, left, rightrow=[-1,1,0,0]col=[0,0,-1,1]forkinrange(4):ni=i+row[k]nj=j+col[k]pathLength=dfs(mat,ni,nj,x,y)# If a valid path is found from this directionifpathLength!=-1:maxPath=max(maxPath,1+pathLength)# Backtrack - restore the cell's original value (1)mat[i][j]=1returnmaxPathdeflongestPath(mat,xs,ys,xd,yd):m=len(mat)n=len(mat[0])# Check if source or destination is blockedifmat[xs][ys]==0ormat[xd][yd]==0:return-1returndfs(mat,xs,ys,xd,yd)#Driver Code Startsdefmain():mat=[[1,1,1,1,1,1,1,1,1,1],[1,1,0,1,1,0,1,1,0,1],[1,1,1,1,1,1,1,1,1,1]]xs,ys=0,0xd,yd=1,7result=longestPath(mat,xs,ys,xd,yd)ifresult!=-1:print(result)else:print(-1)if__name__=="__main__":main()#Driver Code Ends
C#
//Driver Code StartsusingSystem;classGFG{//Driver Code Ends// Function to find the longest path// using backtracking without extra spacestaticintdfs(int[,]mat,inti,intj,intx,inty){intm=mat.GetLength(0);intn=mat.GetLength(1);// If destination is reachedif(i==x&&j==y){return0;}// If cell is invalid or blocked (0 means blocked or visited)if(i<0||i>=m||j<0||j>=n||mat[i,j]==0){return-1;}// Mark current cell as visited by temporarily setting it to 0mat[i,j]=0;intmaxPath=-1;// Four possible moves: up, down, left, rightint[]row={-1,1,0,0};int[]col={0,0,-1,1};for(intk=0;k<4;k++){intni=i+row[k];intnj=j+col[k];intpathLength=dfs(mat,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!=-1){maxPath=Math.Max(maxPath,1+pathLength);}}// Backtrack - restore the cell's original value (1)mat[i,j]=1;returnmaxPath;}staticintlongestPath(int[,]mat,intxs,intys,intxd,intyd){// Check if source or destination is blockedif(mat[xs,ys]==0||mat[xd,yd]==0){return-1;}returndfs(mat,xs,ys,xd,yd);}//Driver Code StartsstaticvoidMain(){int[,]mat={{1,1,1,1,1,1,1,1,1,1},{1,1,0,1,1,0,1,1,0,1},{1,1,1,1,1,1,1,1,1,1}};intxs=0,ys=0;intxd=1,yd=7;intresult=longestPath(mat,xs,ys,xd,yd);if(result!=-1)Console.WriteLine(result);elseConsole.WriteLine(-1);}}//Driver Code Ends
JavaScript
// Function to find the longest path using// backtracking without extra spacefunctiondfs(mat,i,j,x,y){constm=mat.length;constn=mat[0].length;// If destination is reachedif(i===x&&j===y){return0;}// If cell is invalid or blocked (0 means blocked or visited)if(i<0||i>=m||j<0||j>=n||mat[i][j]===0){return-1;}// Mark current cell as visited by temporarily setting it to 0mat[i][j]=0;letmaxPath=-1;// Four possible moves: up, down, left, rightconstrow=[-1,1,0,0];constcol=[0,0,-1,1];for(letk=0;k<4;k++){constni=i+row[k];constnj=j+col[k];constpathLength=dfs(mat,ni,nj,x,y);// If a valid path is found from this directionif(pathLength!==-1){maxPath=Math.max(maxPath,1+pathLength);}}// Backtrack - restore the cell's original value (1)mat[i][j]=1;returnmaxPath;}functionlongestPath(mat,xs,ys,xd,yd){constm=mat.length;constn=mat[0].length;// Check if source or destination is blockedif(mat[xs][ys]===0||mat[xd][yd]===0){return-1;}returndfs(mat,xs,ys,xd,yd);}//Driver Code Starts// Driver Codeconstmat=[[1,1,1,1,1,1,1,1,1,1],[1,1,0,1,1,0,1,1,0,1],[1,1,1,1,1,1,1,1,1,1]];constxs=0,ys=0;constxd=1,yd=7;constresult=longestPath(mat,xs,ys,xd,yd);if(result!==-1)console.log(result);elseconsole.log(-1);//Driver Code Ends