Given a square maze represented by a matrix mat[][] of positive numbers, the task is to find all paths from all four corner cells to the middle cell. From any cell mat[i][j] with value n, you are allowed to move exactly n steps in one of the four cardinal directions—North, South, East, or West. That is, you can move to mat[i + n][j], mat[i - n][j], mat[i][j + n], or mat[i][j - n].
Examples:
Input: mat[][] = [ [ 3, 5, 4, 4, 7, 3, 4, 6, 3 ]
[ 6, 7, 5, 6, 6, 2, 6, 6, 2 ]
[ 3, 3, 4, 3, 2, 5, 4, 7, 2 ]
[ 6, 5, 5, 1, 2, 3, 6, 5, 6 ]
[ 3, 3, 4, 3, 0, 1, 4, 3, 4 ]
[ 3, 5, 4, 3, 2, 2, 3, 3, 5 ]
[ 3, 5, 4, 3, 2, 6, 4, 4, 3 ]
[ 3, 5, 1, 3, 7, 5, 3, 6, 4 ]
[ 6, 2, 4, 3, 4, 5, 4, 5, 1 ] ]
Output: (0, 0) (0, 3) (0, 7) (6, 7) (6, 3) (3, 3) (3, 4) (5, 4) (5, 2) (1, 2) (1, 7) (7, 7) (7, 1) (2, 1) (2, 4) (4, 4)
Explanation: There is one path from top left to the mid (4, 4). Below is given the step-by-step moves to reach the mid cell from top-left cell:
From (0, 0) the cell value is 3, so we move 3 steps to the right, reaching (0, 3).
From (0, 3) the cell value is 4, so we move 4 steps to the right, reaching (0, 7).
From (0, 7) the cell value is 6, so we move 6 steps down, reaching (6, 7).
In the same way, we move remaining cells of the output (6, 7) - > (6, 3) - > (3, 3) -> (3, 4) -> (5, 4) -> (5, 2) -> (1, 2) -> (1, 7) -> (7, 7) -> (7, 1) -> (2, 1) -> (2, 4) -> (4, 4)
Using Backtracking - (4 ^ (n ^ 2)) Time and O(n ^ 2) Space
The idea is to use backtracking by starting with each corner cell of the maze and exploring recursively to determine if a path leads to the destination.
Follow the below given steps:
- Create a 2d array of order n * m to store the visited cells.
- If the destination is reached, store the path.
- Otherwise, mark the current cell as visited and add it to the path array.
- Move forward in all four allowed directions (North, East, West, and South) and recursively check if any of them lead to a solution.
- If none of the moves result in a solution, mark the current cell as not visited and remove it from the path array.
- Repeat this process taking all four corners as starting point.
Below is given the implementation:
#include <bits/stdc++.h>
using namespace std;
// function to find a path from source to destination
void findPath(int x, int y, vector<vector<int>> &path,
vector<vector<int>> &visited, vector<vector<vector<int>>> &res,
vector<vector<int>> &mat) {
int n = mat.size();
// if (x, y) is out of bounds
if (x < 0 || x >= n || y < 0 || y >= n)
return;
// if (x, y) is already visited
if (visited[x][y])
return;
// mark (x, y) as visited
visited[x][y] = 1;
// add (x, y) to path
path.push_back({x, y});
// if (x, y) is the mid cell
if (x == n / 2 && y == n / 2) {
res.push_back(path);
path.pop_back();
visited[x][y] = 0;
return;
}
// search in all four directions
vector<vector<int>> dir = {
{1, 0}, {-1, 0}, {0, 1}, {0, -1}
};
for (int i = 0; i < 4; ++i) {
int u = x + dir[i][0] * mat[x][y];
int v = y + dir[i][1] * mat[x][y];
findPath(u, v, path, visited, res, mat);
}
// backtrack
path.pop_back();
visited[x][y] = 0;
}
// Function to find a path from corner cell to
// middle cell in mat containing positive numbers
vector<vector<vector<int>>> findPathInMaze(
vector<vector<int>> &mat) {
int n = mat.size();
// to store complete path
// from source to destination
vector<vector<vector<int>>> res;
// to mark visited cells
vector<vector<int>> visited(n, vector<int>(n, 0));
// corner cells
vector<vector<int>> corners = {
{0, 0}, {0, n-1}, {n-1, 0}, {n-1, n-1}
};
// to store the path
vector<vector<int>> path;
// Consider each corners as the starting
// point and search in mat
for (int i = 0; i < 4; ++i) {
int x = corners[i][0];
int y = corners[i][1];
findPath(x, y, path, visited, res, mat);
}
return res;
}
int main() {
vector<vector<int>> mat = {
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
vector<vector<vector<int>>> ans = findPathInMaze(mat);
for(int i = 0; i < ans.size(); i++) {
for(int j = 0; j < ans[i].size(); j++) {
cout << "(" << ans[i][j][0] << ", " << ans[i][j][1] << ") ";
}
cout << endl;
}
return 0;
}
import java.util.*;
public class GfG {
// function to find a path from source to destination
static void findPath(int x, int y, List<List<Integer>> path,
List<List<Integer>> visited, List<List<List<Integer>>> res,
int[][] mat) {
int n = mat.length;
// if (x, y) is out of bounds
if (x < 0 || x >= n || y < 0 || y >= n)
return;
// if (x, y) is already visited
if (visited.get(x).get(y) == 1)
return;
// mark (x, y) as visited
visited.get(x).set(y, 1);
// add (x, y) to path
List<Integer> cell = new ArrayList<>();
cell.add(x);
cell.add(y);
path.add(cell);
// if (x, y) is the mid cell
if (x == n / 2 && y == n / 2) {
List<List<Integer>> temp = new ArrayList<>();
for (List<Integer> p : path) {
temp.add(new ArrayList<>(p));
}
res.add(temp);
path.remove(path.size() - 1);
visited.get(x).set(y, 0);
return;
}
// search in all four directions
int[][] dir = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
for (int i = 0; i < 4; ++i) {
int u = x + dir[i][0] * mat[x][y];
int v = y + dir[i][1] * mat[x][y];
findPath(u, v, path, visited, res, mat);
}
// backtrack
path.remove(path.size() - 1);
visited.get(x).set(y, 0);
}
// Function to find a path from corner cell to
// middle cell in mat containing positive numbers
static List<List<List<Integer>>> findPathInMaze(int[][] mat) {
int n = mat.length;
// to store complete path
// from source to destination
List<List<List<Integer>>> res = new ArrayList<>();
// to mark visited cells
List<List<Integer>> visited = new ArrayList<>();
for (int i = 0; i < n; i++) {
List<Integer> row = new ArrayList<>();
for (int j = 0; j < n; j++) {
row.add(0);
}
visited.add(row);
}
// corner cells
int[][] corners = { {0, 0}, {0, n-1}, {n-1, 0}, {n-1, n-1} };
// to store the path
List<List<Integer>> path = new ArrayList<>();
// Consider each corners as the starting
// point and search in mat
for (int i = 0; i < 4; ++i) {
int x = corners[i][0];
int y = corners[i][1];
findPath(x, y, path, visited, res, mat);
}
return res;
}
public static void main(String[] args) {
int[][] mat = {
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
List<List<List<Integer>>> ans = findPathInMaze(mat);
for (List<List<Integer>> path : ans) {
for (List<Integer> cell : path) {
System.out.print("(" + cell.get(0) + ", " + cell.get(1) + ") ");
}
System.out.println();
}
}
}
mod = 1000000007
# function to find a path from source to destination
def findPath(x, y, path, visited, res, mat):
n = len(mat)
# if (x, y) is out of bounds
if x < 0 or x >= n or y < 0 or y >= n:
return
# if (x, y) is already visited
if visited[x][y]:
return
# mark (x, y) as visited
visited[x][y] = 1
# add (x, y) to path
path.append([x, y])
# if (x, y) is the mid cell
if x == n // 2 and y == n // 2:
res.append(path.copy())
path.pop()
visited[x][y] = 0
return
# search in all four directions
dir = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for i in range(4):
u = x + dir[i][0] * mat[x][y]
v = y + dir[i][1] * mat[x][y]
findPath(u, v, path, visited, res, mat)
# backtrack
path.pop()
visited[x][y] = 0
# Function to find a path from corner cell to
# middle cell in mat containing positive numbers
def findPathInMaze(mat):
n = len(mat)
# to store complete path
# from source to destination
res = []
# to mark visited cells
visited = [[0 for _ in range(n)] for _ in range(n)]
# corner cells
corners = [[0, 0], [0, n - 1], [n - 1, 0], [n - 1, n - 1]]
# to store the path
path = []
# Consider each corners as the starting
# point and search in mat
for corner in corners:
x = corner[0]
y = corner[1]
findPath(x, y, path, visited, res, mat)
return res
if __name__ == "__main__":
mat = [
[3, 5, 4, 4, 7, 3, 4, 6, 3],
[6, 7, 5, 6, 6, 2, 6, 6, 2],
[3, 3, 4, 3, 2, 5, 4, 7, 2],
[6, 5, 5, 1, 2, 3, 6, 5, 6],
[3, 3, 4, 3, 0, 1, 4, 3, 4],
[3, 5, 4, 3, 2, 2, 3, 3, 5],
[3, 5, 4, 3, 2, 6, 4, 4, 3],
[3, 5, 1, 3, 7, 5, 3, 6, 4],
[6, 2, 4, 3, 4, 5, 4, 5, 1]
]
ans = findPathInMaze(mat)
for path in ans:
for cell in path:
print("({0}, {1}) ".format(cell[0], cell[1]), end="")
print()
using System;
using System.Collections.Generic;
public class GfG {
// function to find a path from source to destination
static void FindPath(int x, int y, List<List<int>> path,
List<List<int>> visited, List<List<List<int>>> res, int[][] mat) {
int n = mat.Length;
// if (x, y) is out of bounds
if (x < 0 || x >= n || y < 0 || y >= n)
return;
// if (x, y) is already visited
if (visited[x][y] == 1)
return;
// mark (x, y) as visited
visited[x][y] = 1;
// add (x, y) to path
List<int> cell = new List<int> { x, y };
path.Add(cell);
// if (x, y) is the mid cell
if (x == n / 2 && y == n / 2) {
List<List<int>> temp = new List<List<int>>();
foreach (var p in path) {
temp.Add(new List<int>(p));
}
res.Add(temp);
path.RemoveAt(path.Count - 1);
visited[x][y] = 0;
return;
}
// search in all four directions
int[][] dir = new int[][] {
new int[] {1, 0}, new int[] {-1, 0},
new int[] {0, 1}, new int[] {0, -1}
};
for (int i = 0; i < 4; ++i) {
int u = x + dir[i][0] * mat[x][y];
int v = y + dir[i][1] * mat[x][y];
FindPath(u, v, path, visited, res, mat);
}
// backtrack
path.RemoveAt(path.Count - 1);
visited[x][y] = 0;
}
// Function to find a path from corner cell to
// middle cell in mat containing positive numbers
static List<List<List<int>>> FindPathInMaze(int[][] mat) {
int n = mat.Length;
// to store complete path
// from source to destination
List<List<List<int>>> res = new List<List<List<int>>>();
// to mark visited cells
List<List<int>> visited = new List<List<int>>();
for (int i = 0; i < n; i++) {
List<int> row = new List<int>();
for (int j = 0; j < n; j++) {
row.Add(0);
}
visited.Add(row);
}
// corner cells
int[][] corners = new int[][] {
new int[] {0, 0}, new int[] {0, n-1},
new int[] {n-1, 0}, new int[] {n-1, n-1}
};
// to store the path
List<List<int>> path = new List<List<int>>();
// Consider each corners as the starting
// point and search in mat
for (int i = 0; i < 4; ++i) {
int x = corners[i][0];
int y = corners[i][1];
FindPath(x, y, path, visited, res, mat);
}
return res;
}
public static void Main(string[] args) {
int[][] mat = new int[][] {
new int[] { 3, 5, 4, 4, 7, 3, 4, 6, 3 },
new int[] { 6, 7, 5, 6, 6, 2, 6, 6, 2 },
new int[] { 3, 3, 4, 3, 2, 5, 4, 7, 2 },
new int[] { 6, 5, 5, 1, 2, 3, 6, 5, 6 },
new int[] { 3, 3, 4, 3, 0, 1, 4, 3, 4 },
new int[] { 3, 5, 4, 3, 2, 2, 3, 3, 5 },
new int[] { 3, 5, 4, 3, 2, 6, 4, 4, 3 },
new int[] { 3, 5, 1, 3, 7, 5, 3, 6, 4 },
new int[] { 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
List<List<List<int>>> ans = FindPathInMaze(mat);
foreach (var path in ans) {
foreach (var cell in path) {
Console.Write("(" + cell[0] + ", " + cell[1] + ") ");
}
Console.WriteLine();
}
}
}
// function to find a path from source to destination
function findPath(x, y, path, visited, res, mat) {
let n = mat.length;
// if (x, y) is out of bounds
if (x < 0 || x >= n || y < 0 || y >= n)
return;
// if (x, y) is already visited
if (visited[x][y])
return;
// mark (x, y) as visited
visited[x][y] = 1;
// add (x, y) to path
path.push([x, y]);
// if (x, y) is the mid cell
if (x === Math.floor(n / 2) && y === Math.floor(n / 2)) {
res.push(path.map(cell => [cell[0], cell[1]]));
path.pop();
visited[x][y] = 0;
return;
}
// search in all four directions
let dir = [
[1, 0], [-1, 0], [0, 1], [0, -1]
];
for (let i = 0; i < 4; ++i) {
let u = x + dir[i][0] * mat[x][y];
let v = y + dir[i][1] * mat[x][y];
findPath(u, v, path, visited, res, mat);
}
// backtrack
path.pop();
visited[x][y] = 0;
}
// Function to find a path from corner cell to
// middle cell in mat containing positive numbers
function findPathInMaze(mat) {
let n = mat.length;
// to store complete path
// from source to destination
let res = [];
// to mark visited cells
let visited = [];
for (let i = 0; i < n; i++) {
visited.push(new Array(n).fill(0));
}
// corner cells
let corners = [
[0, 0], [0, n - 1], [n - 1, 0], [n - 1, n - 1]
];
// to store the path
let path = [];
// Consider each corners as the starting
// point and search in mat
for (let i = 0; i < 4; ++i) {
let x = corners[i][0];
let y = corners[i][1];
findPath(x, y, path, visited, res, mat);
}
return res;
}
function main() {
let mat = [
[ 3, 5, 4, 4, 7, 3, 4, 6, 3 ],
[ 6, 7, 5, 6, 6, 2, 6, 6, 2 ],
[ 3, 3, 4, 3, 2, 5, 4, 7, 2 ],
[ 6, 5, 5, 1, 2, 3, 6, 5, 6 ],
[ 3, 3, 4, 3, 0, 1, 4, 3, 4 ],
[ 3, 5, 4, 3, 2, 2, 3, 3, 5 ],
[ 3, 5, 4, 3, 2, 6, 4, 4, 3 ],
[ 3, 5, 1, 3, 7, 5, 3, 6, 4 ],
[ 6, 2, 4, 3, 4, 5, 4, 5, 1 ]
];
let ans = findPathInMaze(mat);
for (let i = 0; i < ans.length; i++) {
let path = ans[i];
let line = "";
for (let j = 0; j < path.length; j++) {
line += "(" + path[j][0] + ", " + path[j][1] + ") ";
}
console.log(line);
}
}
main();
Output
(0, 0) (0, 3) (0, 7) (6, 7) (6, 3) (3, 3) (3, 4) (5, 4) (5, 2) (1, 2) (1, 7) (7, 7) (7, 1) (2, 1) (2, 4) (4, 4)