Longest Possible Route in a Matrix (original) (raw)
Given a 2D binary matrix **mat[][] where 0 represent hurdle and 1 free cell. Find the **length of the longest path from a source (xs, ys) to a destination (xd, yd) with these rules:
- Move only up, down, left, or right (no diagonals).
- Each cell can be visited at most once in a path.
- If reaching the destination is impossible, return -1.
**Examples:
**Input: xs = 0, ys = 0, xd = 1, yd = 7
mat[][] = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 1, 1, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
**Output: 24
**Explanation:
**Input: xs = 0, ys = 3, xd = 2, yd = 2
mat[][] =[ [1, 0, 0, 1, 0],
[0, 0, 0, 1, 0],
[0, 1, 1, 0, 0]]
**Output: -1
**Explanation: We can see that it is impossible to reach the cell (2,2) from (0,3).
Table of Content
- [Approach] Using Backtracking with Visited Matrix - O(4^(m*n)) Time and O(m*n) Space
- [Optimized Approach] Without Using Extra Space - O(4^(m*n)) Time and O(1) Space
[Approach] Using Backtracking with Visited Matrix - O(4(m*n)) Time and O(m*n) Space
The idea is to use backtracking. We start from the source cell and recursively explore all four allowed directions—up, down, left, and right while keeping track of the cells already visited using a visited array. For each move, we mark the current cell as visited and continue exploring valid adjacent cells. If we reach the destination, we update the length of the longest path found so far. After exploring a path, we backtrack by unmarking the cell in the visited array so it can be used in other paths.
C++ `
//Driver Code Starts #include #include #include #include using namespace std;
//Driver Code Ends
// Function to find the longest path using backtracking int dfs(vector<vector> &mat, vector<vector> &visited, int i, int j, int x, int y) { int m = mat.size(); int n = mat[0].size();
// If destination is reached
if (i == x && j == y) {
return 0;
}
// If cell is invalid, blocked, or already visited
if (i < 0 || i >= m || j < 0 || j >= n ||
mat[i][j] == 0 || visited[i][j]) {
return -1;
}
// Mark current cell as visited
visited[i][j] = true;
int maxPath = -1;
// Four possible moves: up, down, left, right
int row[] = {-1, 1, 0, 0};
int col[] = {0, 0, -1, 1};
for (int k = 0; k < 4; k++) {
int ni = i + row[k];
int nj = j + col[k];
int pathLength = dfs(mat, visited,
ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength != -1) {
maxPath = max(maxPath, 1 + pathLength);
}
}
// Backtrack - unmark current cell
visited[i][j] = false;
return maxPath;}
int longestPath(vector<vector> &mat, int xs, int ys, int xd, int yd) { int m = mat.size(); int n = mat[0].size();
// Check if source or destination is blocked
if (mat[xs][ys] == 0 || mat[xd][yd] == 0) {
return -1;
}
vector<vector<bool>> visited(m, vector<bool>(n, false));
return dfs(mat, visited, xs, ys, xd, yd);}
//Driver Code Starts
int main() { vector<vector> mat = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 0, 1, 1, 0, 1, 1, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };
int xs = 0, ys = 0;
int xd = 1, yd = 7;
int result = longestPath(mat, xs, ys, xd, yd);
if (result != -1)
cout << result << endl;
else
cout << -1 << endl;
return 0;} //Driver Code Ends
Java
//Driver Code Starts import java.util.Arrays;
class GFG {
//Driver Code Ends
// Function to find the longest path using backtracking
static int dfs(int[][] mat, boolean[][] visited,
int i, int j, int x, int y) {
int m = mat.length;
int n = mat[0].length;
// If destination is reached
if (i == x && j == y) {
return 0;
}
// If cell is invalid, blocked, or already visited
if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0 || visited[i][j]) {
return -1; // Invalid path
}
// Mark current cell as visited
visited[i][j] = true;
int maxPath = -1;
// Four possible moves: up, down, left, right
int[] row = {-1, 1, 0, 0};
int[] col = {0, 0, -1, 1};
for (int k = 0; k < 4; k++) {
int ni = i + row[k];
int nj = j + col[k];
int pathLength = dfs(mat, visited, ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength != -1) {
maxPath = Math.max(maxPath, 1 + pathLength);
}
}
// Backtrack - unmark current cell
visited[i][j] = false;
return maxPath;
}
static int longestPath(int[][] mat, int xs, int ys, int xd, int yd) {
int m = mat.length;
int n = mat[0].length;
// Check if source or destination is blocked
if (mat[xs][ys] == 0 || mat[xd][yd] == 0) {
return -1;
}
boolean[][] visited = new boolean[m][n];
return dfs(mat, visited, xs, ys, xd, yd);
}//Driver Code Starts
public static void main(String[] args) {
int[][] mat = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int xs = 0, ys = 0;
int xd = 1, yd = 7;
int result = longestPath(mat, xs, ys, xd, yd);
if (result != -1)
System.out.println(result);
else
System.out.println(-1);
}} //Driver Code Ends
Python
Function to find the longest path using backtracking
def dfs(mat, visited, i, j, x, y): m = len(mat) n = len(mat[0])
# If destination is reached
if i == x and j == y:
return 0
# If cell is invalid, blocked, or already visited
if i < 0 or i >= m or j < 0 or j >= n or mat[i][j] == 0 or visited[i][j]:
return -1 # Invalid path
# Mark current cell as visited
visited[i][j] = True
maxPath = -1
# Four possible moves: up, down, left, right
row = [-1, 1, 0, 0]
col = [0, 0, -1, 1]
for k in range(4):
ni = i + row[k]
nj = j + col[k]
pathLength = dfs(mat, visited, ni, nj, x, y)
# If a valid path is found from this direction
if pathLength != -1:
maxPath = max(maxPath, 1 + pathLength)
# Backtrack - unmark current cell
visited[i][j] = False
return maxPathdef longestPath(mat, xs, ys, xd, yd): m = len(mat) n = len(mat[0])
# Check if source or destination is blocked
if mat[xs][ys] == 0 or mat[xd][yd] == 0:
return -1
visited = [[False for _ in range(n)] for _ in range(m)]
return dfs(mat, visited, xs, ys, xd, yd)#Driver Code Starts if name == "main": mat = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ]
xs, ys = 0, 0
xd, yd = 1, 7
result = longestPath(mat, xs, ys, xd, yd)
if result != -1:
print(result)
else:
print(-1)#Driver Code Ends
C#
//Driver Code Starts using System;
class GFG {
//Driver Code Ends
// Function to find the longest path using backtracking
static int dfs(int[,] mat, bool[,] visited,
int i, int j, int x, int y) {
int m = mat.GetLength(0);
int n = mat.GetLength(1);
// If destination is reached
if (i == x && j == y) {
return 0;
}
// If cell is invalid, blocked, or already visited
if (i < 0 || i >= m || j < 0 || j >= n || mat[i, j] == 0 || visited[i, j]) {
return -1; // Invalid path
}
// Mark current cell as visited
visited[i, j] = true;
int maxPath = -1;
// Four possible moves: up, down, left, right
int[] row = {-1, 1, 0, 0};
int[] col = {0, 0, -1, 1};
for (int k = 0; k < 4; k++)
{
int ni = i + row[k];
int nj = j + col[k];
int pathLength = dfs(mat, visited, ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength != -1)
{
maxPath = Math.Max(maxPath, 1 + pathLength);
}
}
// Backtrack - unmark current cell
visited[i, j] = false;
return maxPath;
}
static int longestPath(int[,] mat, int xs, int ys, int xd, int yd) {
int m = mat.GetLength(0);
int n = mat.GetLength(1);
// Check if source or destination is blocked
if (mat[xs, ys] == 0 || mat[xd, yd] == 0)
{
return -1;
}
bool[,] visited = new bool[m, n];
return dfs(mat, visited, xs, ys, xd, yd);
}//Driver Code Starts
static void Main() {
int[,] mat = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int xs = 0, ys = 0;
int xd = 1, yd = 7;
int result = longestPath(mat, xs, ys, xd, yd);
if (result != -1)
Console.WriteLine(result);
else
Console.WriteLine(-1);
}} //Driver Code Ends
JavaScript
// Function to find the longest path using backtracking function dfs(mat, visited, i, j, x, y) { const m = mat.length; const n = mat[0].length;
// If destination is reached
if (i === x && j === y) {
return 0;
}
// If cell is invalid, blocked, or already visited
if (i < 0 || i >= m || j < 0 || j >= n ||
mat[i][j] === 0 || visited[i][j]) {
return -1;
}
// Mark current cell as visited
visited[i][j] = true;
let maxPath = -1;
// Four possible moves: up, down, left, right
const row = [-1, 1, 0, 0];
const col = [0, 0, -1, 1];
for (let k = 0; k < 4; k++) {
const ni = i + row[k];
const nj = j + col[k];
const pathLength = dfs(mat, visited,
ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength !== -1) {
maxPath = Math.max(maxPath, 1 + pathLength);
}
}
// Backtrack - unmark current cell
visited[i][j] = false;
return maxPath;}
function longestPath(mat, xs, ys, xd, yd) { const m = mat.length; const n = mat[0].length;
// Check if source or destination is blocked
if (mat[xs][ys] === 0 || mat[xd][yd] === 0) {
return -1;
}
const visited = Array(m).fill().map(() => Array(n).fill(false));
return dfs(mat, visited, xs, ys, xd, yd);}
//Driver Code Starts // Driver Code const mat = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ];
const xs = 0, ys = 0;
const xd = 1, yd = 7;
const result = longestPath(mat, xs, ys, xd, yd);
if (result !== -1)
console.log(result);
else
console.log(-1);//Driver Code Ends
`
Instead of using a separate visited matrix, mark cells as visited directly in the input matrix by setting them to 0. Explore all four directions recursively. After finishing a path from a cell, restore its value to 1 (backtracking).
C++ `
//Driver Code Starts #include #include #include #include using namespace std;
//Driver Code Ends
// Function to find the longest path using backtracking without extra space int dfs(vector<vector> &mat, int i, int j, int x, int y) { int m = mat.size(); int n = mat[0].size();
// If destination is reached
if (i == x && j == y) {
return 0;
}
// If cell is invalid or blocked (0 means blocked or visited)
if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0) {
return -1;
}
// Mark current cell as visited by temporarily setting it to 0
mat[i][j] = 0;
int maxPath = -1;
// Four possible moves: up, down, left, right
int row[] = {-1, 1, 0, 0};
int col[] = {0, 0, -1, 1};
for (int k = 0; k < 4; k++) {
int ni = i + row[k];
int nj = j + col[k];
int pathLength = dfs(mat, ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength != -1) {
maxPath = max(maxPath, 1 + pathLength);
}
}
// Backtrack - restore the cell's original value (1)
mat[i][j] = 1;
return maxPath;}
int longestPath(vector<vector> &mat, int xs, int ys, int xd, int yd) { int m = mat.size(); int n = mat[0].size();
// Check if source or destination is blocked
if (mat[xs][ys] == 0 || mat[xd][yd] == 0) {
return -1;
}
return dfs(mat, xs, ys, xd, yd);}
//Driver Code Starts
int main() { vector<vector> mat = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 0, 1, 1, 0, 1, 1, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };
int xs = 0, ys = 0;
int xd = 1, yd = 7;
int result = longestPath(mat, xs, ys, xd, yd);
if (result != -1)
cout << result << endl;
else
cout << -1 << endl;
return 0;} //Driver Code Ends
Java
//Driver Code Starts class GFG {
//Driver Code Ends
// Function to find the longest path using
// backtracking without extra space
static int dfs(int[][] mat, int i, int j, int x, int y) {
int m = mat.length;
int n = mat[0].length;
// If destination is reached
if (i == x && j == y) {
return 0;
}
// If cell is invalid or blocked (0 means blocked or visited)
if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0) {
return -1;
}
// Mark current cell as visited by temporarily setting it to 0
mat[i][j] = 0;
int maxPath = -1;
// Four possible moves: up, down, left, right
int[] row = {-1, 1, 0, 0};
int[] col = {0, 0, -1, 1};
for (int k = 0; k < 4; k++) {
int ni = i + row[k];
int nj = j + col[k];
int pathLength = dfs(mat, ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength != -1) {
maxPath = Math.max(maxPath, 1 + pathLength);
}
}
// Backtrack - restore the cell's original value (1)
mat[i][j] = 1;
return maxPath;
}
static int longestPath(int[][] mat, int xs, int ys, int xd, int yd) {
int m = mat.length;
int n = mat[0].length;
// Check if source or destination is blocked
if (mat[xs][ys] == 0 || mat[xd][yd] == 0) {
return -1;
}
return dfs(mat, xs, ys, xd, yd);
}//Driver Code Starts
public static void main(String[] args) {
int[][] mat = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int xs = 0, ys = 0;
int xd = 1, yd = 7;
int result = longestPath(mat, xs, ys, xd, yd);
if (result != -1)
System.out.println(result);
else
System.out.println(-1);
}} //Driver Code Ends
Python
Function to find the longest path
using backtracking without extra space
def dfs(mat, i, j, x, y): m = len(mat) n = len(mat[0])
# If destination is reached
if i == x and j == y:
return 0
# If cell is invalid or blocked (0 means blocked or visited)
if i < 0 or i >= m or j < 0 or j >= n or mat[i][j] == 0:
return -1
# Mark current cell as visited by temporarily setting it to 0
mat[i][j] = 0
maxPath = -1
# Four possible moves: up, down, left, right
row = [-1, 1, 0, 0]
col = [0, 0, -1, 1]
for k in range(4):
ni = i + row[k]
nj = j + col[k]
pathLength = dfs(mat, ni, nj, x, y)
# If a valid path is found from this direction
if pathLength != -1:
maxPath = max(maxPath, 1 + pathLength)
# Backtrack - restore the cell's original value (1)
mat[i][j] = 1
return maxPathdef longestPath(mat, xs, ys, xd, yd): m = len(mat) n = len(mat[0])
# Check if source or destination is blocked
if mat[xs][ys] == 0 or mat[xd][yd] == 0:
return -1
return dfs(mat, xs, ys, xd, yd)#Driver Code Starts def main(): mat = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ]
xs, ys = 0, 0
xd, yd = 1, 7
result = longestPath(mat, xs, ys, xd, yd)
if result != -1:
print(result)
else:
print(-1)if name == "main": main() #Driver Code Ends
C#
//Driver Code Starts using System;
class GFG {
//Driver Code Ends
// Function to find the longest path
// using backtracking without extra space
static int dfs(int[,] mat, int i, int j, int x, int y) {
int m = mat.GetLength(0);
int n = mat.GetLength(1);
// If destination is reached
if (i == x && j == y)
{
return 0;
}
// If cell is invalid or blocked (0 means blocked or visited)
if (i < 0 || i >= m || j < 0 || j >= n || mat[i, j] == 0)
{
return -1;
}
// Mark current cell as visited by temporarily setting it to 0
mat[i, j] = 0;
int maxPath = -1;
// Four possible moves: up, down, left, right
int[] row = {-1, 1, 0, 0};
int[] col = {0, 0, -1, 1};
for (int k = 0; k < 4; k++)
{
int ni = i + row[k];
int nj = j + col[k];
int pathLength = dfs(mat, ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength != -1)
{
maxPath = Math.Max(maxPath, 1 + pathLength);
}
}
// Backtrack - restore the cell's original value (1)
mat[i, j] = 1;
return maxPath;
}
static int longestPath(int[,] mat, int xs, int ys, int xd, int yd)
{
// Check if source or destination is blocked
if (mat[xs, ys] == 0 || mat[xd, yd] == 0)
{
return -1;
}
return dfs(mat, xs, ys, xd, yd);
}//Driver Code Starts
static void Main()
{
int[,] mat = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int xs = 0, ys = 0;
int xd = 1, yd = 7;
int result = longestPath(mat, xs, ys, xd, yd);
if (result != -1)
Console.WriteLine(result);
else
Console.WriteLine(-1);
}} //Driver Code Ends
JavaScript
// Function to find the longest path using // backtracking without extra space function dfs(mat, i, j, x, y) { const m = mat.length; const n = mat[0].length;
// If destination is reached
if (i === x && j === y) {
return 0;
}
// If cell is invalid or blocked (0 means blocked or visited)
if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] === 0) {
return -1;
}
// Mark current cell as visited by temporarily setting it to 0
mat[i][j] = 0;
let maxPath = -1;
// Four possible moves: up, down, left, right
const row = [-1, 1, 0, 0];
const col = [0, 0, -1, 1];
for (let k = 0; k < 4; k++) {
const ni = i + row[k];
const nj = j + col[k];
const pathLength = dfs(mat, ni, nj, x, y);
// If a valid path is found from this direction
if (pathLength !== -1) {
maxPath = Math.max(maxPath, 1 + pathLength);
}
}
// Backtrack - restore the cell's original value (1)
mat[i][j] = 1;
return maxPath;}
function longestPath(mat, xs, ys, xd, yd) { const m = mat.length; const n = mat[0].length;
// Check if source or destination is blocked
if (mat[xs][ys] === 0 || mat[xd][yd] === 0) {
return -1;
}
return dfs(mat, xs, ys, xd, yd);}
//Driver Code Starts // Driver Code const mat = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ];
const xs = 0, ys = 0;
const xd = 1, yd = 7;
const result = longestPath(mat, xs, ys, xd, yd);
if (result !== -1)
console.log(result);
else
console.log(-1);//Driver Code Ends
`
