先决条件–递归,回溯和堆栈数据结构。
迷宫以块的N * M二进制矩阵形式给出,最初有(0,0)处有老鼠。迷宫[0] [0],老鼠想吃在迷宫中某个给定区域存在的食物(fx,fy)。在迷宫矩阵中,0表示该块是死胡同,而1表示该块可以在从源到目标的路径中使用。老鼠可以沿任何方向(不是对角线)移动到任何块,只要该块不是死胡同即可。
任务是检查是否存在任何路径,以使老鼠可以进食或不进食。不需要打印路径。
例子:
Input : maze[4][5] = {
{1, 0, 1, 1, 0},
{1, 1, 1, 0, 1},
{0, 1, 0, 1, 1},
{1, 1, 1, 1, 1}
}
fx = 2, fy=3
Output : Path Found!
The path can be: (0, 0) -> (1, 0) -> (1, 1) -> (2, 1) -> (3, 1) -> (3, 2) -> (3, 3) -> (2, 3)
这是许多访谈中都问到的著名的“迷宫中的老鼠”问题,可以使用递归和回溯来解决。我们已经讨论了在迷宫中使用Rat中的递归来解决此问题的回溯解决方案。回溯2。在此讨论了使用堆栈的迭代解决方案。
在上一篇文章中,递归使用调用堆栈来保持存储每个递归调用,然后在函数结束时弹出。我们将通过使用自己的堆栈来执行相同的操作来消除递归。
节点结构用于存储从该节点探索的(i,j)坐标和方向以及下一步尝试的方向。
Structure Used:
- X : x coordinate of the node
- Y : y coordinate of the node
- dir : This variable will be used to tell which all directions we have tried and which to choose next. We will try all the directions in anti-clockwise manner starting from Up. Initially it will be assigned 0.
- If dir=0 try Up direction.
- If dir=1 try left direction.
- If dir=2 try down direction.
- If dir=3 try right direction.
Else retract back to the previous block of the maze.
最初,我们将索引为i = 0,j = 0和dir = 0的节点压入堆栈。我们将以逆时针的方式逐个移动到最顶层节点的所有方向,并且每次尝试新路径时,我们都会将该节点(迷宫块)推入堆栈中。每次都会增加最顶层节点的dir变量,以便每次尝试新的方向时都可以,除非探索了所有方向。 dir = 4。如果dir等于4,我们将从堆栈中弹出该节点,这意味着我们正在退回一步,返回到我们来自的路径。
我们还将维护一个访问矩阵,该矩阵将维护迷宫的哪些块已在路径中使用,或换句话说已在堆栈中使用。在尝试任何方向时,我们还将检查迷宫的障碍物是否不是死胡同,并且也未超出迷宫。
我们将在最上面的节点坐标等于食物的坐标(这意味着我们已经到达食物)或堆栈变空(这意味着没有可能到达食物的路径)的同时执行此操作。
下面是上述方法的实现:
C++
// CPP program to solve Rat in a maze
// problem with backtracking using stack
#include
#include
#include
using namespace std;
#define N 4
#define M 5
class node {
public:
int x, y;
int dir;
node(int i, int j)
{
x = i;
y = j;
// Initially direction
// set to 0
dir = 0;
}
};
// maze of n*m matrix
int n = N, m = M;
// Coordinates of food
int fx, fy;
bool visited[N][M];
bool isReachable(int maze[N][M])
{
// Initially starting at (0, 0).
int i = 0, j = 0;
stack s;
node temp(i, j);
s.push(temp);
while (!s.empty()) {
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.top();
int d = temp.dir;
i = temp.x, j = temp.y;
// Increment the direction and
// push the node in the stack again.
temp.dir++;
s.pop();
s.push(temp);
// If we reach the Food coordinates
// return true
if (i == fx and j == fy) {
return true;
}
// Checking the Up direction.
if (d == 0) {
if (i - 1 >= 0 and maze[i - 1][j] and
visited[i - 1][j]) {
node temp1(i - 1, j);
visited[i - 1][j] = false;
s.push(temp1);
}
}
// Checking the left direction
else if (d == 1) {
if (j - 1 >= 0 and maze[i][j - 1] and
visited[i][j - 1]) {
node temp1(i, j - 1);
visited[i][j - 1] = false;
s.push(temp1);
}
}
// Checking the down direction
else if (d == 2) {
if (i + 1 < n and maze[i + 1][j] and
visited[i + 1][j]) {
node temp1(i + 1, j);
visited[i + 1][j] = false;
s.push(temp1);
}
}
// Checking the right direction
else if (d == 3) {
if (j + 1 < m and maze[i][j + 1] and
visited[i][j + 1]) {
node temp1(i, j + 1);
visited[i][j + 1] = false;
s.push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else {
visited[temp.x][temp.y] = true;
s.pop();
}
}
// If the stack is empty and
// no path is found return false.
return false;
}
// Driver code
int main()
{
// Initially setting the visited
// array to true (unvisited)
memset(visited, true, sizeof(visited));
// Maze matrix
int maze[N][M] = {
{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 }
};
// Food coordinates
fx = 2;
fy = 3;
if (isReachable(maze)) {
cout << "Path Found!" << '\n';
}
else
cout << "No Path Found!" << '\n';
return 0;
}
Java
// Java program to solve Rat in a maze
// problem with backtracking using stack
import java.util.Stack;
class Node
{
private int x, y;
private int dir;
public Node(int i, int j)
{
this.x = i;
this.y = j;
// default value for direction set to 0 (Up)
this.dir = 0;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
public int getDir()
{
return dir;
}
public void setDir(int dir)
{
this.dir = dir;
}
}
public class RatInMaze
{
private static final int N = 4;
private static final int M = 5;
// maze of n*m matrix
int n = N, m = M;
private static boolean[][] visited = new boolean[N][M];
// Driver code
public static void main(String[] args)
{
// Initially setting the visited
// array to true (unvisited)
setVisited(true);
// Maze matrix
int maze[][] = {{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 } };
if (isReachable(maze))
{
System.out.println("Path Found!\n");
}
else
System.out.println("No Path Found!\n");
}
private static void setVisited(boolean b)
{
for (int i = 0; i < visited.length; i++)
{
for (int j = 0; j < visited[i].length; j++)
{
visited[i][j] = b;
}
}
}
private static boolean isReachable(int maze[][])
{
// Initially starting at (0, 0).
int i = 0, j = 0;
// Food coordinates
// Coordinates of food
int fx, fy;
fx = 2;
fy = 3;
Stack s = new Stack();
Node temp = new Node(i, j);
s.push(temp);
while (!s.empty())
{
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.peek();
int d = temp.getDir();
i = temp.getX();
j = temp.getY();
// Increment the direction and
// push the node in the stack again.
temp.setDir(temp.getDir() + 1);
s.pop();
s.push(temp);
// If we reach the Food coordinates
// return true
if (i == fx && j == fy)
{
return true;
}
if (d == 0)
{
// Checking the Up direction.
if (i - 1 >= 0 && maze[i - 1][j] == 1 &&
visited[i - 1][j])
{
Node temp1 = new Node(i - 1, j);
visited[i - 1][j] = false;
s.push(temp1);
}
}
else if (d == 1)
{
// Checking the left direction
if (j - 1 >= 0 && maze[i][j - 1] == 1 &&
visited[i][j - 1])
{
Node temp1 = new Node(i, j - 1);
visited[i][j - 1] = false;
s.push(temp1);
}
}
else if (d == 2)
{
// Checking the down direction
if (i + 1 < N && maze[i + 1][j] == 1 &&
visited[i + 1][j])
{
Node temp1 = new Node(i + 1, j);
visited[i + 1][j] = false;
s.push(temp1);
}
}
else if (d == 3)
{
// Checking the right direction
if (j + 1 < M && maze[i][j + 1] == 1 &&
visited[i][j + 1])
{
Node temp1 = new Node(i, j + 1);
visited[i][j + 1] = false;
s.push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else
{
visited[temp.getX()][temp.getY()] = true;
s.pop();
}
}
// If the stack is empty and
// no path is found return false.
return false;
}
}
// This code is contributed by nirajtechi
C#
// C# program to solve Rat in a maze
// problem with backtracking using stack
using System;
using System.Collections.Generic;
public class Node
{
private int x, y;
private int dir;
public Node(int i, int j)
{
this.x = i;
this.y = j;
// default value for direction set to 0 (Up)
this.dir = 0;
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
public int getDir()
{
return dir;
}
public void setDir(int dir)
{
this.dir = dir;
}
}
public class RatInMaze
{
private static readonly int N = 4;
private static readonly int M = 5;
// maze of n*m matrix
int n = N, m = M;
private static bool [,]visited = new bool[N,M];
// Driver code
public static void Main(String[] args)
{
// Initially setting the visited
// array to true (unvisited)
setVisited(true);
// Maze matrix
int [,]maze = {{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 } };
if (isReachable(maze))
{
Console.WriteLine("Path Found!\n");
}
else
Console.WriteLine("No Path Found!\n");
}
private static void setVisited(bool b)
{
for (int i = 0; i < visited.GetLength(0); i++)
{
for (int j = 0; j < visited.GetLength(0); j++)
{
visited[i,j] = b;
}
}
}
private static bool isReachable(int [,]maze)
{
// Initially starting at (0, 0).
int i = 0, j = 0;
// Food coordinates
// Coordinates of food
int fx, fy;
fx = 2;
fy = 3;
Stack s = new Stack();
Node temp = new Node(i, j);
s.Push(temp);
while (s.Count!=0)
{
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.Peek();
int d = temp.getDir();
i = temp.getX();
j = temp.getY();
// Increment the direction and
// push the node in the stack again.
temp.setDir(temp.getDir() + 1);
s.Pop();
s.Push(temp);
// If we reach the Food coordinates
// return true
if (i == fx && j == fy)
{
return true;
}
if (d == 0)
{
// Checking the Up direction.
if (i - 1 >= 0 && maze[i - 1,j] == 1 &&
visited[i - 1,j])
{
Node temp1 = new Node(i - 1, j);
visited[i - 1,j] = false;
s.Push(temp1);
}
}
else if (d == 1)
{
// Checking the left direction
if (j - 1 >= 0 && maze[i,j - 1] == 1 &&
visited[i,j - 1])
{
Node temp1 = new Node(i, j - 1);
visited[i,j - 1] = false;
s.Push(temp1);
}
}
else if (d == 2)
{
// Checking the down direction
if (i + 1 < N && maze[i + 1,j] == 1 &&
visited[i + 1,j])
{
Node temp1 = new Node(i + 1, j);
visited[i + 1,j] = false;
s.Push(temp1);
}
}
else if (d == 3)
{
// Checking the right direction
if (j + 1 < M && maze[i,j + 1] == 1 &&
visited[i,j + 1])
{
Node temp1 = new Node(i, j + 1);
visited[i,j + 1] = false;
s.Push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else
{
visited[temp.getX(),temp.getY()] = true;
s.Pop();
}
}
// If the stack is empty and
// no path is found return false.
return false;
}
}
// This code contributed by Rajput-Ji
Path Found!
注意:我们也可以通过仅将节点弹出堆栈来打印路径,然后以相反的顺序打印它们。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。