Given a binary matrix maze[][] of size n × n containing values 0 and 1, find all possible paths for a rat to travel from the source cell (0, 0) to the destination cell (n - 1, n - 1). The rat can move in four directions: up, down, left, and right.
1 represents an open cell through which the rat can move.
0 represents a blocked cell that cannot be traversed.
The rat can move only through open cells and cannot visit the same cell more than once in a path. Return all valid paths as strings consisting of 'U', 'D', 'L', and 'R', representing the sequence of moves taken by the rat.
Note: Return the paths in lexicographically increasing order. If no valid path exists, return an empty list.
Example:
Input: maze[][] = {{1, 0, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 0}, {0, 1, 1, 1}} Output: ["DDRDRR", "DRDDRR"] Explanation: There are two valid paths from the source cell (0, 0) to the destination cell (3, 3)
Input: maze[][] = {{1, 0}, {0, 1}} Output: [] Explanation: No path exists as the destination cell (1, 1) is blocked.
[Approach] Using DFS and Backtracking - O(4^(n^2)) Time and O(n^2) Space
The idea is to use DFS to explore all possible paths from the source cell (0, 0) to the destination cell (n - 1, n - 1). For each cell, we try moving in all four directions: D, L, R, and U.
To avoid revisiting a cell in the same path, the current cell is temporarily marked as blocked before exploring its neighbors. After exploring all possible paths through that cell, it is restored to its original value (backtracking). Whenever the destination is reached, the current path is added to the result. Finally, all collected paths are sorted to obtain lexicographical order.
Start DFS from (0, 0).
Temporarily mark the current cell as blocked.
Explore all valid neighboring cells in the order D, L, R, U.
Append the corresponding direction to the path and recurse.
When the destination is reached, store the path.
Backtrack by removing the last direction and restoring the current cell.
Sort all collected paths before returning the result.
C++
#include<iostream>#include<vector>#include<string>#include<algorithm>usingnamespacestd;// Directions: Down, Left, Right, Upstringdir="DLRU";intdr[4]={1,0,0,-1};intdc[4]={0,-1,1,0};// Check if a cell is valid (inside the maze and open)boolisValid(intr,intc,intn,vector<vector<int>>&maze){returnr>=0&&c>=0&&r<n&&c<n&&maze[r][c];}// Function to find all valid pathsvoidfindPath(intr,intc,vector<vector<int>>&maze,string&path,vector<string>&res){intn=maze.size();// If destination is reached, store the pathif(r==n-1&&c==n-1){res.push_back(path);return;}// Mark current cell as visitedmaze[r][c]=0;for(inti=0;i<4;i++){intnr=r+dr[i],nc=c+dc[i];if(isValid(nr,nc,n,maze)){path.push_back(dir[i]);// Move to the next cell recursivelyfindPath(nr,nc,maze,path,res);// Backtrackpath.pop_back();}}// Unmark current cellmaze[r][c]=1;}// Function to find all paths and return themvector<string>ratInMaze(vector<vector<int>>&maze){vector<string>result;intn=maze.size();stringpath="";if(maze[0][0]==1&&maze[n-1][n-1]==1){// Start from (0,0)findPath(0,0,maze,path,result);}// Sort results lexicographicallysort(result.begin(),result.end());returnresult;}intmain(){vector<vector<int>>maze={{1,0,0,0},{1,1,0,1},{1,1,0,0},{0,1,1,1}};vector<string>result=ratInMaze(maze);for(autop:result){cout<<p<<" ";}return0;}
Java
importjava.util.ArrayList;importjava.util.Collections;classGFG{// Directions: Down, Left, Right, UpstaticStringdir="DLRU";staticint[]dr={1,0,0,-1};staticint[]dc={0,-1,1,0};// Check if a cell is valid (inside the maze and open)staticbooleanisValid(intr,intc,intn,int[][]maze){returnr>=0&&c>=0&&r<n&&c<n&&maze[r][c]==1;}// Function to find all valid pathsstaticvoidfindPath(intr,intc,int[][]maze,StringBuilderpath,ArrayList<String>res){intn=maze.length;// If destination is reached, store the pathif(r==n-1&&c==n-1){res.add(path.toString());return;}// Mark current cell as visitedmaze[r][c]=0;for(inti=0;i<4;i++){intnr=r+dr[i],nc=c+dc[i];if(isValid(nr,nc,n,maze)){path.append(dir.charAt(i));// Move to the next cell recursivelyfindPath(nr,nc,maze,path,res);// Backtrackpath.deleteCharAt(path.length()-1);}}// Unmark current cellmaze[r][c]=1;}// Function to find all paths and return themstaticArrayList<String>ratInMaze(int[][]maze){ArrayList<String>result=newArrayList<>();intn=maze.length;StringBuilderpath=newStringBuilder();if(maze[0][0]==1&&maze[n-1][n-1]==1){// Start from (0,0)findPath(0,0,maze,path,result);}// Sort results lexicographicallyCollections.sort(result);returnresult;}publicstaticvoidmain(String[]args){int[][]maze={{1,0,0,0},{1,1,0,1},{1,1,0,0},{0,1,1,1}};ArrayList<String>result=ratInMaze(maze);for(Stringp:result){System.out.print(p+" ");}}}
Python
# Directions: Down, Left, Right, Updir="DLRU"dr=[1,0,0,-1]dc=[0,-1,1,0]# Check if a cell is valid (inside the maze and open)defisValid(r,c,n,maze):returnr>=0andc>=0andr<nandc<nandmaze[r][c]==1# Function to find all valid pathsdeffindPath(r,c,maze,path,res):n=len(maze)# If destination is reached, store the pathifr==n-1andc==n-1:res.append("".join(path))return# Mark current cell as visitedmaze[r][c]=0foriinrange(4):nr,nc=r+dr[i],c+dc[i]ifisValid(nr,nc,n,maze):path.append(dir[i])# Move to the next cell recursivelyfindPath(nr,nc,maze,path,res)# Backtrackpath.pop()# Unmark current cellmaze[r][c]=1# Function to find all paths and return themdefratInMaze(maze):result=[]n=len(maze)path=[]ifmaze[0][0]==1andmaze[n-1][n-1]==1:# Start from (0,0)findPath(0,0,maze,path,result)# Sort results lexicographicallyresult.sort()returnresultif__name__=="__main__":maze=[[1,0,0,0],[1,1,0,1],[1,1,0,0],[0,1,1,1]]result=ratInMaze(maze)forpinresult:print(p,end=" ")
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Directions: Down, Left, Right, Upstaticstringdir="DLRU";staticint[]dr={1,0,0,-1};staticint[]dc={0,-1,1,0};// Check if a cell is valid (inside the maze and open)staticboolisValid(intr,intc,intn,int[,]maze){returnr>=0&&c>=0&&r<n&&c<n&&maze[r,c]==1;}// Function to find all valid pathsstaticvoidfindPath(intr,intc,int[,]maze,List<char>path,List<string>res){intn=maze.GetLength(0);// If destination is reached, store the pathif(r==n-1&&c==n-1){res.Add(newstring(path.ToArray()));return;}// Mark current cell as visitedmaze[r,c]=0;for(inti=0;i<4;i++){intnr=r+dr[i],nc=c+dc[i];if(isValid(nr,nc,n,maze)){path.Add(dir[i]);// Move to the next cell recursivelyfindPath(nr,nc,maze,path,res);// Backtrackpath.RemoveAt(path.Count-1);}}// Unmark current cellmaze[r,c]=1;}// Function to find all paths and return themstaticList<string>ratInMaze(int[,]maze){List<string>result=newList<string>();intn=maze.GetLength(0);List<char>path=newList<char>();if(maze[0,0]==1&&maze[n-1,n-1]==1){// Start from (0,0)findPath(0,0,maze,path,result);}// Sort results lexicographicallyresult.Sort();returnresult;}publicstaticvoidMain(string[]args){int[,]maze={{1,0,0,0},{1,1,0,1},{1,1,0,0},{0,1,1,1}};List<string>result=ratInMaze(maze);foreach(stringpinresult){Console.Write(p+" ");}}}
JavaScript
// Directions: Down, Left, Right, Upconstdir="DLRU";constdr=[1,0,0,-1];constdc=[0,-1,1,0];// Check if a cell is valid (inside the maze and open)functionisValid(r,c,n,maze){returnr>=0&&c>=0&&r<n&&c<n&&maze[r][c]===1;}// Function to find all valid pathsfunctionfindPath(r,c,maze,path,res){constn=maze.length;// If destination is reached, store the pathif(r===n-1&&c===n-1){res.push(path);return;}// Mark current cell as visitedmaze[r][c]=0;for(leti=0;i<4;i++){constnr=r+dr[i],nc=c+dc[i];if(isValid(nr,nc,n,maze)){path+=dir[i];// Move to the next cell recursivelyfindPath(nr,nc,maze,path,res);// Backtrackpath=path.slice(0,-1);}}// Unmark current cellmaze[r][c]=1;}// Function to find all paths and return themfunctionratInMaze(maze){letresult=[];constn=maze.length;letpath="";if(maze[0][0]===1&&maze[n-1][n-1]===1){// Start from (0,0)findPath(0,0,maze,path,result);}// Sort results lexicographicallyresult.sort();returnresult;}// Driver Codeconstmaze=[[1,0,0,0],[1,1,0,1],[1,1,0,0],[0,1,1,1]];constresult=ratInMaze(maze);console.log(result.join(" "));