Maze With N doors and 1 Key
Given an N * N binary maze where a 0 denotes that the position can be visited and a 1 denotes that the position cannot be visited without a key, the task is to find whether it is possible to visit the bottom-right cell from the top-left cell with only one key along the way. If possible then print “Yes” else print “No”.
Example:
Input: maze[][] = {
{0, 0, 1},
{1, 0, 1},
{1, 1, 0}}
Output: Yes
Approach: This problem can be solved using recursion, for every possible move, if the current cell is 0 then without altering the status of the key check whether it is the destination else move forward. If the current cell is 1 then the key must be used, now for the further moves the key will be set to false i.e. it’ll never be used again on the same path. If any path reaches the destination then print Yes else print No.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Recursive function to check whether there is // a path from the top left cell to the // bottom right cell of the maze bool findPath(vector<vector< int > > maze, int xpos, int ypos, bool key) { // Check whether the current cell is // within the maze if (xpos < 0 || xpos >= maze.size() || ypos < 0 || ypos >= maze.size()) return false ; // If key is required to move further if (maze[xpos][ypos] == '1' ) { // If the key hasn't been used before if (key == true ) // If current cell is the destination if (xpos == maze.size() - 1 && ypos == maze.size() - 1) return true ; // Either go down or right return findPath(maze, xpos + 1, ypos, false ) || findPath(maze, xpos, ypos + 1, false ); // Key has been used before return false ; } // If current cell is the destination if (xpos == maze.size() - 1 && ypos == maze.size() - 1) return true ; // Either go down or right return findPath(maze, xpos + 1, ypos, key) || findPath(maze, xpos, ypos + 1, key); } bool mazeProb(vector<vector< int > > maze, int xpos, int ypos) { bool key = true ; if (findPath(maze, xpos, ypos, key)) return true ; return false ; } // Driver code int main() { vector<vector< int > > maze = { { '0' , '0' , '1' }, { '1' , '0' , '1' }, { '1' , '1' , '0' } }; int n = maze.size(); // If there is a path from the cell (0, 0) if (mazeProb(maze, 0, 0)) cout << "Yes" ; else cout << "No" ; } // This code is contributed by grand_master |
Java
// Java implementation of the approach import java.io.*; import java.util.ArrayList; class GFG { // Recursive function to check whether there // is a path from the top left cell to the // bottom right cell of the maze static boolean findPath(ArrayList<ArrayList<Integer> > maze, int xpos, int ypos, boolean key) { // Check whether the current cell is // within the maze if (xpos < 0 || xpos >= maze.size() || ypos < 0 || ypos >= maze.size()) return false ; // If key is required to move further if (maze.get(xpos).get(ypos) == '1' ) { // If the key hasn't been used before if (key == true ) // If current cell is the destination if (xpos == maze.size() - 1 && ypos == maze.size() - 1 ) return true ; // Either go down or right return findPath(maze, xpos + 1 , ypos, false ) || findPath(maze, xpos, ypos + 1 , false ); } // If current cell is the destination if (xpos == maze.size() - 1 && ypos == maze.size() - 1 ) return true ; // Either go down or right return findPath(maze, xpos + 1 , ypos, key) || findPath(maze, xpos, ypos + 1 , key); } static boolean mazeProb(ArrayList<ArrayList<Integer> > maze, int xpos, int ypos) { boolean key = true ; if (findPath(maze, xpos, ypos, key)) return true ; return false ; } // Driver code public static void main(String[] args) { int size = 3 ; ArrayList<ArrayList<Integer> > maze = new ArrayList<ArrayList<Integer> >(size); for ( int i = 0 ; i < size; i++) { maze.add( new ArrayList<Integer>()); } // We are making these //{ { '0', '0', '1' }, // { '1', '0', '1' }, // { '1', '1', '0' } }; maze.get( 0 ).add( 0 ); maze.get( 0 ).add( 0 ); maze.get( 0 ).add( 1 ); maze.get( 1 ).add( 1 ); maze.get( 1 ).add( 0 ); maze.get( 1 ).add( 1 ); maze.get( 2 ).add( 1 ); maze.get( 2 ).add( 1 ); maze.get( 2 ).add( 0 ); // If there is a path from the cell (0, 0) if (mazeProb(maze, 0 , 0 )) System.out.print( "Yes" ); else System.out.print( "No" ); } } // This code is contributed by sujitmeshram |
Python3
# Python3 implementation of the approach # Recursive function to check whether there is # a path from the top left cell to the # bottom right cell of the maze def findPath(maze, xpos, ypos, key): # Check whether the current cell is # within the maze if xpos < 0 or xpos > = len (maze) or ypos < 0 \ or ypos > = len (maze): return False # If key is required to move further if maze[xpos][ypos] = = '1' : # If the key hasn't been used before if key = = True : # If current cell is the destination if xpos = = len (maze) - 1 and ypos = = len (maze) - 1 : return True # Either go down or right return findPath(maze, xpos + 1 , ypos, False ) or \ findPath(maze, xpos, ypos + 1 , False ) # Key has been used before return False # If current cell is the destination if xpos = = len (maze) - 1 and ypos = = len (maze) - 1 : return True # Either go down or right return findPath(maze, xpos + 1 , ypos, key) or \ findPath(maze, xpos, ypos + 1 , key) def mazeProb(maze, xpos, ypos): key = True if findPath(maze, xpos, ypos, key): return True return False # Driver code if __name__ = = "__main__" : maze = [[ '0' , '0' , '1' ], [ '1' , '0' , '1' ], [ '1' , '1' , '0' ]] n = len (maze) # If there is a path from the cell (0, 0) if mazeProb(maze, 0 , 0 ): print ( "Yes" ) else : print ( "No" ) |
C#
// C# implementation of the approach using System; using System.Collections.Generic; class GFG { // Recursive function to check whether there // is a path from the top left cell to the // bottom right cell of the maze static bool findPath(List<List< int > > maze, int xpos, int ypos, bool key) { // Check whether the current cell is // within the maze if (xpos < 0 || xpos >= maze.Count || ypos < 0 || ypos >= maze.Count) return false ; // If key is required to move further if (maze[xpos][ypos] == '1' ) { // If the key hasn't been used before if (key == true ) // If current cell is the destination if (xpos == maze.Count - 1 && ypos == maze.Count - 1) return true ; // Either go down or right return findPath(maze, xpos + 1, ypos, false ) || findPath(maze, xpos, ypos + 1, false ); } // If current cell is the destination if (xpos == maze.Count - 1 && ypos == maze.Count - 1) return true ; // Either go down or right return findPath(maze, xpos + 1, ypos, key) || findPath(maze, xpos, ypos + 1, key); } static bool mazeProb(List<List< int > > maze, int xpos, int ypos) { bool key = true ; if (findPath(maze, xpos, ypos, key)) return true ; return false ; } // Driver code public static void Main(String[] args) { int size = 3; List<List< int > > maze = new List<List< int > >(size); for ( int i = 0; i < size; i++) { maze.Add( new List< int >()); } // We are making these //{ { '0', '0', '1' }, // { '1', '0', '1' }, // { '1', '1', '0' } }; maze[0].Add(0); maze[0].Add(0); maze[0].Add(1); maze[1].Add(1); maze[1].Add(0); maze[1].Add(1); maze[2].Add(1); maze[2].Add(1); maze[2].Add(0); // If there is a path from the cell (0, 0) if (mazeProb(maze, 0, 0)) Console.Write( "Yes" ); else Console.Write( "No" ); } } // This code is contributed by gauravrajput1 |
Javascript
<script> // JavaScript implementation of the approach // Recursive function to check whether there is // a path from the top left cell to the // bottom right cell of the maze function findPath(maze, xpos, ypos, key) { // Check whether the current cell is // within the maze if (xpos < 0 || xpos >= maze.length || ypos < 0 || ypos >= maze.length) return false ; // If key is required to move further if (maze[xpos][ypos] == '1' ) { // If the key hasn't been used before if (key == true ) // If current cell is the destination if (xpos == maze.length - 1 && ypos == maze.length - 1) return true ; // Either go down or right return findPath(maze, xpos + 1, ypos, false ) || findPath(maze, xpos, ypos + 1, false ); // Key has been used before return false ; } // If current cell is the destination if (xpos == maze.length - 1 && ypos == maze.length - 1) return true ; // Either go down or right return findPath(maze, xpos + 1, ypos, key) || findPath(maze, xpos, ypos + 1, key); } function mazeProb(maze, xpos, ypos) { let key = true ; if (findPath(maze, xpos, ypos, key)) return true ; return false ; } // Driver code let maze = [ [ '0 ', ' 0 ', ' 1 ' ], [ ' 1 ', ' 0 ', ' 1 ' ], [ ' 1 ', ' 1 ', ' 0' ] ]; let n = maze.length; // If there is a path from the cell (0, 0) if (mazeProb(maze, 0, 0)) document.write( "Yes" ); else document.write( "No" ); </script> |
Yes
Time Complexity: O(2N)
Optimized Approach:
Dynamic Programming can be used to improve the time complexity
The main idea is for every cell the answer is dependent upon its previous row and col .
Here maze[1][1] is dependent on maze[1][0] or maze[0][1] if it is a possible path .
Hence using this approach we can compute result of maze[n-1][n-1] from its previous adjacent cells
And also there are some edge condition for 0th row and 0th col as the these cells are dependent on their previous col and row respectively.
Bellow is the implementation of above approach.
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; bool mazeProb(vector<vector< int > > maze, int n) { for ( int row = 0; row < n; ++row) { for ( int col = 0; col < n; ++col) { if (row == 0 && col == 0) // Skip the first cell continue ; if (row == 0) { // for first row result depend on previous col maze[row][col] = min( 2, maze[row][col] + maze[row][col - 1]); } else if (col == 0) { // for first col result depends on previous row maze[row][col] = min( 2, maze[row][col] + maze[row - 1][col]); } else { // for other cells, result will be // minimum of previous row or col cell maze[row][col] = min(2, maze[row][col] + min(maze[row][col - 1], maze[row - 1][col])); } } } return maze[n - 1][n - 1] != 2; // if last cell value is 2 then there is no // path available } // Driver code int main() { vector<vector< int > > maze = { { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 0 } }; int n = maze.size(); // If there is a path from the cell (0, 0) if (mazeProb(maze, 3)) cout << "Yes" ; else cout << "No" ; } // This code is contributed by pratham sonawane |
Java
// Java implementation of the approach import java.util.ArrayList; public class GFG { static boolean mazeProb(ArrayList< int []> maze, int n) { for ( int row = 0 ; row < n; ++row) { for ( int col = 0 ; col < n; ++col) { if (row == 0 && col == 0 ) // Skip the first cell continue ; if (row == 0 ) { // for first row result depend on // previous col maze.get(row)[col] = Math.min( 2 , maze.get(row)[col] + maze.get(row)[col - 1 ]); } else if (col == 0 ) { // for first col result depends on // previous row maze.get(row)[col] = Math.min( 2 , maze.get(row)[col] + maze.get(row - 1 )[col]); } else { // for other cells, result will be // minimum of previous row or col cell maze.get(row)[col] = Math.min( 2 , maze.get(row)[col] + Math.min( maze.get(row)[col - 1 ], maze.get(row - 1 )[col])); } } } return maze.get(n - 1 )[n - 1 ] != 2 ; // if last cell value is 2 then there is // no path available } // Driver code public static void main(String[] args) { ArrayList< int []> maze = new ArrayList< int []>(); maze.add( new int [] { 0 , 0 , 1 }); maze.add( new int [] { 1 , 0 , 1 }); maze.add( new int [] { 1 , 1 , 0 }); int n = maze.size(); // If there is a path from the cell (0, 0) if (mazeProb(maze, 3 )) System.out.println( "Yes" ); else System.out.println( "No" ); } } // This code is contributed by Lovely Jain |
Python3
# Python implementation of the approach def mazeProb(maze, n): for row in range (n): for col in range (n): if (row = = 0 and col = = 0 ): # Skip the first cell continue if (row = = 0 ): # for first row result depend on previous col maze[row][col] = min ( 2 , maze[row][col] + maze[row][col - 1 ]) elif (col = = 0 ): # for first col result depends on previous row maze[row][col] = min ( 2 , maze[row][col] + maze[row - 1 ][col]) else : # for other cells, result will be # minimum of previous row or col cell maze[row][col] = min ( 2 , maze[row][col] + min (maze[row][col - 1 ], maze[row - 1 ][col])) return maze[n - 1 ][n - 1 ]! = 2 # if last cell value is 2 then there is no # path available # Driver code maze = [ [ 0 , 0 , 1 ], [ 1 , 0 , 1 ], [ 1 , 1 , 0 ] ] n = len (maze) # If there is a path from the cell (0, 0) if (mazeProb(maze, 3 )): print ( "Yes" ) else : print ( "No" ) # This code is contributed by shinjanpatra |
C#
//C# code for the above approach using System; using System.Collections.Generic; class GFG { static bool mazeProb(List< int []> maze, int n) { for ( int row = 0; row < n; ++row) { for ( int col = 0; col < n; ++col) { if (row == 0 && col == 0) // Skip the first cell continue ; if (row == 0) { // for first row result depend on // previous col maze[row][col] = Math.Min( 2, maze[row][col] + maze[row][col - 1]); } else if (col == 0) { // for first col result depends on // previous row maze[row][col] = Math.Min( 2, maze[row][col] + maze[row - 1][col]); } else { // for other cells, result will be // minimum of previous row or col cell maze[row][col] = Math.Min( 2, maze[row][col] + Math.Min(maze[row][col - 1], maze[row - 1][col])); } } } return maze[n - 1][n - 1] != 2; // if last cell value is 2 then there is // no path available } // Driver code public static void Main() { List< int []> maze = new List< int []>(); maze.Add( new int [] { 0, 0, 1 }); maze.Add( new int [] { 1, 0, 1 }); maze.Add( new int [] { 1, 1, 0 }); int n = maze.Count; // If there is a path from the cell (0, 0) if (mazeProb(maze, 3)) Console.WriteLine( "Yes" ); else Console.WriteLine( "No" ); } } // This code is contributed by pradeepkumarppk2003 |
Javascript
<script> // JavaScript implementation of the approach function mazeProb(maze,n) { for (let row = 0; row < n; ++row) { for (let col = 0; col < n; ++col) { if (row == 0 && col == 0) // Skip the first cell continue ; if (row == 0) { // for first row result depend on previous col maze[row][col] = Math.min( 2, maze[row][col] + maze[row][col - 1]); } else if (col == 0) { // for first col result depends on previous row maze[row][col] = Math.min( 2, maze[row][col] + maze[row - 1][col]); } else { // for other cells, result will be // minimum of previous row or col cell maze[row][col] = Math.min(2, maze[row][col] + Math.min(maze[row][col - 1], maze[row - 1][col])); } } } return maze[n - 1][n - 1]!= 2; // if last cell value is 2 then there is no // path available } // Driver code let maze = [ [ 0, 0, 1 ], [ 1, 0, 1 ], [ 1, 1, 0 ] ]; let n = maze.length; // If there is a path from the cell (0, 0) if (mazeProb(maze, 3)) document.write( "Yes" ); else document.write( "No" ); // This code is contributed by shinjanpatra </script> |
Yes
Time Complexity: O(N^2)
Space Complexity: O(1)
Please Login to comment...