Skip to content
Related Articles

Related Articles

Improve Article
Rat in a Maze Problem when movement in all possible directions is allowed
  • Difficulty Level : Medium
  • Last Updated : 15 Jan, 2021

Consider a rat placed at (0, 0) in a square matrix m[ ][ ] of order n and has to reach the destination at (n-1, n-1). The task is to find a sorted array of strings denoting all the possible directions which the rat can take to reach the destination at (n-1, n-1). The directions in which the rat can move are ‘U'(up), ‘D'(down), ‘L’ (left), ‘R’ (right).

Examples: 

Input : N = 4 
1 0 0 0 
1 1 0 1 
0 1 0 0 
0 1 1 1
Output :
DRDDRR

Input :N = 4 
1 0 0 0 
1 1 0 1 
1 1 0 0 
0 1 1 1
Output :
DDRDRR DRDDRR
Explanation: 



Solution: 
Approach: 

  1. Start from the initial index (i.e. (0,0)) and look for the valid moves through the adjacent cells in the order Down->Left->Right->Up (so as to get the sorted paths) in the grid.
  2. If the move is possible, then move to that cell while storing the character corresponding to the move(D,L,R,U) and again start looking for the valid move until the last index (i.e. (n-1,n-1)) is reached.
  3. Also, keep on marking the cells as visited and when we traversed all the paths possible from that cell, then unmark that cell for other different paths and remove the character from the path formed.
  4. As the last index of the grid(bottom right) is reached, then store the traversed path.

Below is the implementation of the above approach:  

C++




// C++ implementation of the above approach
#include <bits/stdc++.h>
#define MAX 5
using namespace std;
 
// Function returns true if the
// move taken is valid else
// it will return false.
bool isSafe(int row, int col, int m[][MAX],
                 int n, bool visited[][MAX])
{
    if (row == -1 || row == n || col == -1 ||
                  col == n || visited[row][col]
                           || m[row][col] == 0)
        return false;
 
    return true;
}
 
// Function to print all the possible
// paths from (0, 0) to (n-1, n-1).
void printPathUtil(int row, int col, int m[][MAX],
              int n, string& path, vector<string>&
               possiblePaths, bool visited[][MAX])
{
    // This will check the initial point
    // (i.e. (0, 0)) to start the paths.
    if (row == -1 || row == n || col == -1
               || col == n || visited[row][col]
                           || m[row][col] == 0)
        return;
 
    // If reach the last cell (n-1, n-1)
    // then store the path and return
    if (row == n - 1 && col == n - 1) {
        possiblePaths.push_back(path);
        return;
    }
 
    // Mark the cell as visited
    visited[row][col] = true;
 
    // Try for all the 4 directions (down, left,
    // right, up) in the given order to get the
    // paths in lexicographical order
 
    // Check if downward move is valid
    if (isSafe(row + 1, col, m, n, visited))
    {
        path.push_back('D');
        printPathUtil(row + 1, col, m, n,
                 path, possiblePaths, visited);
        path.pop_back();
    }
 
    // Check if the left move is valid
    if (isSafe(row, col - 1, m, n, visited))
    {
        path.push_back('L');
        printPathUtil(row, col - 1, m, n,
                   path, possiblePaths, visited);
        path.pop_back();
    }
 
    // Check if the right move is valid
    if (isSafe(row, col + 1, m, n, visited))
    {
        path.push_back('R');
        printPathUtil(row, col + 1, m, n,
                   path, possiblePaths, visited);
        path.pop_back();
    }
 
     // Check if the upper move is valid
    if (isSafe(row - 1, col, m, n, visited))
    {
        path.push_back('U');
        printPathUtil(row - 1, col, m, n,
               path, possiblePaths, visited);
        path.pop_back();
    }
 
    // Mark the cell as unvisited for
    // other possible paths
    visited[row][col] = false;
}
 
// Function to store and print
// all the valid paths
void printPath(int m[MAX][MAX], int n)
{
    // vector to store all the possible paths
    vector<string> possiblePaths;
    string path;
    bool visited[n][MAX];
    memset(visited, false, sizeof(visited));
      
    // Call the utility function to
    // find the valid paths
    printPathUtil(0, 0, m, n, path,
                      possiblePaths, visited);
 
    // Print all possible paths
    for (int i = 0; i < possiblePaths.size(); i++)
        cout << possiblePaths[i] << " ";
}
 
// Driver code
int main()
{
    int m[MAX][MAX] = { { 1, 0, 0, 0, 0 },
                        { 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 0, 1 },
                        { 0, 0, 0, 0, 1 },
                        { 0, 0, 0, 0, 1 } };
    int n = sizeof(m) / sizeof(m[0]);
    printPath(m, n);
 
    return 0;
}

Java




// Java implementation of the above approach
import java.util.*;
 
class GFG{
     
// Vector to store all the possible paths
static Vector<String> possiblePaths = new Vector<>();
static String path = "";
static final int MAX =  5;
 
// Function returns true if the
// move taken is valid else
// it will return false.
static boolean isSafe(int row, int col, int m[][],
                      int n, boolean visited[][])
{
    if (row == -1 || row == n || col == -1 ||
         col == n || visited[row][col] ||
                     m[row][col] == 0)
        return false;
 
    return true;
}
 
// Function to print all the possible
// paths from (0, 0) to (n-1, n-1).
static void printPathUtil(int row, int col, int m[][],
                          int n, boolean visited[][])
{
     
    // This will check the initial point
    // (i.e. (0, 0)) to start the paths.
    if (row == -1 || row == n || col == -1 ||
         col == n || visited[row][col] ||
                     m[row][col] == 0)
        return;
 
    // If reach the last cell (n-1, n-1)
    // then store the path and return
    if (row == n - 1 && col == n - 1)
    {
        possiblePaths.add(path);
        return;
    }
 
    // Mark the cell as visited
    visited[row][col] = true;
 
    // Try for all the 4 directions (down, left,
    // right, up) in the given order to get the
    // paths in lexicographical order
 
    // Check if downward move is valid
    if (isSafe(row + 1, col, m, n, visited))
    {
        path += 'D';
        printPathUtil(row + 1, col, m, n,
                      visited);
        path = path.substring(0, path.length() - 1);
    }
 
    // Check if the left move is valid
    if (isSafe(row, col - 1, m, n, visited))
    {
        path += 'L';
        printPathUtil(row, col - 1, m, n,
                      visited);
        path = path.substring(0, path.length() - 1);
    }
 
    // Check if the right move is valid
    if (isSafe(row, col + 1, m, n, visited))
    {
        path += 'R';
        printPathUtil(row, col + 1, m, n,
                      visited);
        path = path.substring(0, path.length() - 1);
    }
 
    // Check if the upper move is valid
    if (isSafe(row - 1, col, m, n, visited))
    {
        path += 'U';
        printPathUtil(row - 1, col, m, n,
                      visited);
        path = path.substring(0, path.length() - 1);
    }
 
    // Mark the cell as unvisited for
    // other possible paths
    visited[row][col] = false;
}
 
// Function to store and print
// all the valid paths
static void printPath(int m[][], int n)
{
    boolean [][]visited = new boolean[n][MAX];
     
    // Call the utility function to
    // find the valid paths
    printPathUtil(0, 0, m, n, visited);
 
    // Print all possible paths
    for(int i = 0; i < possiblePaths.size(); i++)
        System.out.print(possiblePaths.get(i) + " ");
}
 
// Driver code
public static void main(String[] args)
{
    int m[][] = { { 1, 0, 0, 0, 0 },
                  { 1, 1, 1, 1, 1 },
                  { 1, 1, 1, 0, 1 },
                  { 0, 0, 0, 0, 1 },
                  { 0, 0, 0, 0, 1 } };
    int n = m.length;
     
    printPath(m, n);
}
}
 
// This code is contributed by gauravrajput1

Python3




# Python3 implementation of the above approach
from typing import List
 
MAX = 5
 
# Function returns true if the
# move taken is valid else
# it will return false.
def isSafe(row: int, col: int,
           m: List[List[int]], n: int,
           visited: List[List[bool]]) -> bool:
 
    if (row == -1 or row == n or
        col == -1 or col == n or
        visited[row][col] or m[row][col] == 0):
        return False
 
    return True
 
# Function to print all the possible
# paths from (0, 0) to (n-1, n-1).
def printPathUtil(row: int, col: int,
                  m: List[List[int]],
                  n: int, path: str,
                  possiblePaths: List[str],
                  visited: List[List[bool]]) -> None:
 
    # This will check the initial point
    # (i.e. (0, 0)) to start the paths.
    if (row == -1 or row == n or
        col == -1 or col == n or
        visited[row][col] or m[row][col] == 0):
        return
 
    # If reach the last cell (n-1, n-1)
    # then store the path and return
    if (row == n - 1 and col == n - 1):
        possiblePaths.append(path)
        return
 
    # Mark the cell as visited
    visited[row][col] = True
 
    # Try for all the 4 directions (down, left,
    # right, up) in the given order to get the
    # paths in lexicographical order
 
    # Check if downward move is valid
    if (isSafe(row + 1, col, m, n, visited)):
        path += 'D'
        printPathUtil(row + 1, col, m, n,
                      path, possiblePaths, visited)
        path = path[:-1]
 
    # Check if the left move is valid
    if (isSafe(row, col - 1, m, n, visited)):
        path += 'L'
        printPathUtil(row, col - 1, m, n,
                      path, possiblePaths, visited)
        path = path[:-1]
 
    # Check if the right move is valid
    if (isSafe(row, col + 1, m, n, visited)):
        path += 'R'
        printPathUtil(row, col + 1, m, n,
                      path, possiblePaths, visited)
        path = path[:-1]
 
    # Check if the upper move is valid
    if (isSafe(row - 1, col, m, n, visited)):
        path += 'U'
        printPathUtil(row - 1, col, m, n,
                      path, possiblePaths, visited)
        path = path[:-1]
 
    # Mark the cell as unvisited for
    # other possible paths
    visited[row][col] = False
 
# Function to store and print
# all the valid paths
def printPath(m: List[List[int]], n: int) -> None:
 
    # vector to store all the possible paths
    possiblePaths = []
    path = ""
    visited = [[False for _ in range(MAX)]
                      for _ in range(n)]
                       
    # Call the utility function to
    # find the valid paths
    printPathUtil(0, 0, m, n, path,
                  possiblePaths, visited)
 
    # Print all possible paths
    for i in range(len(possiblePaths)):
        print(possiblePaths[i], end = " ")
 
# Driver code
if __name__ == "__main__":
     
    m = [ [ 1, 0, 0, 0, 0 ],
          [ 1, 1, 1, 1, 1 ],
          [ 1, 1, 1, 0, 1 ],
          [ 0, 0, 0, 0, 1 ],
          [ 0, 0, 0, 0, 1 ] ]
    n = len(m)
     
    printPath(m, n)
 
# This code is contributed by sanjeev2552

C#




// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG{
     
// List to store all the possible paths
static List<String> possiblePaths = new List<String>();
static String path = "";
static readonly int MAX =  5;
 
// Function returns true if the
// move taken is valid else
// it will return false.
static bool isSafe(int row, int col, int [,]m,
                      int n, bool [,]visited)
{
    if (row == -1 || row == n || col == -1 ||
         col == n || visited[row,col] ||
                     m[row,col] == 0)
        return false;
    return true;
}
 
// Function to print all the possible
// paths from (0, 0) to (n-1, n-1).
static void printPathUtil(int row, int col, int [,]m,
                          int n, bool [,]visited)
{
     
    // This will check the initial point
    // (i.e. (0, 0)) to start the paths.
    if (row == -1 || row == n || col == -1 ||
         col == n || visited[row,col] ||
                     m[row,col] == 0)
        return;
 
    // If reach the last cell (n-1, n-1)
    // then store the path and return
    if (row == n - 1 && col == n - 1)
    {
        possiblePaths.Add(path);
        return;
    }
 
    // Mark the cell as visited
    visited[row,col] = true;
 
    // Try for all the 4 directions (down, left,
    // right, up) in the given order to get the
    // paths in lexicographical order
 
    // Check if downward move is valid
    if (isSafe(row + 1, col, m, n, visited))
    {
        path += 'D';
        printPathUtil(row + 1, col, m, n,
                      visited);
        path = path.Substring(0, path.Length - 1);
    }
 
    // Check if the left move is valid
    if (isSafe(row, col - 1, m, n, visited))
    {
        path += 'L';
        printPathUtil(row, col - 1, m, n,
                      visited);
        path = path.Substring(0, path.Length - 1);
    }
 
    // Check if the right move is valid
    if (isSafe(row, col + 1, m, n, visited))
    {
        path += 'R';
        printPathUtil(row, col + 1, m, n,
                      visited);
        path = path.Substring(0, path.Length - 1);
    }
 
    // Check if the upper move is valid
    if (isSafe(row - 1, col, m, n, visited))
    {
        path += 'U';
        printPathUtil(row - 1, col, m, n,
                      visited);
        path = path.Substring(0, path.Length - 1);
    }
 
    // Mark the cell as unvisited for
    // other possible paths
    visited[row,col] = false;
}
 
// Function to store and print
// all the valid paths
static void printPath(int [,]m, int n)
{
    bool [,]visited = new bool[n,MAX];
     
    // Call the utility function to
    // find the valid paths
    printPathUtil(0, 0, m, n, visited);
 
    // Print all possible paths
    for(int i = 0; i < possiblePaths.Count; i++)
        Console.Write(possiblePaths[i] + " ");
}
 
// Driver code
public static void Main(String[] args)
{
    int [,]m = { { 1, 0, 0, 0, 0 },
                  { 1, 1, 1, 1, 1 },
                  { 1, 1, 1, 0, 1 },
                  { 0, 0, 0, 0, 1 },
                  { 0, 0, 0, 0, 1 } };
    int n = m.GetLength(0);  
    printPath(m, n);
}
}
 
// This code is contributed by gauravrajput1
Output: 
DDRRURRDDD DDRURRRDDD DRDRURRDDD DRRRRDDD

 

Complexity Analysis: 

  • Time Complexity: O(3^(n^2)). 
    As there are N^2 cells from each cell there are 3 unvisited neighbouring cells. So the time complexity O(3^(N^2).
  • Auxiliary Space: O(3^(n^2)). 
    As there can be atmost 3^(n^2) cells in the answer so the space complexity is O(3^(n^2)).

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :