Longest Possible Route in a Matrix

Last Updated : 11 Jul, 2026

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: 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 = 0, ys = 0, xd = 1, yd = 7
Output: 24
Explanation: The longest valid path from (0, 0) to (1, 7) without revisiting any cell has length 24.

blobid1_1782119611

Input: mat[][] =[ [1, 0, 0, 1, 0], [0, 0, 0, 1, 0], [0, 1, 1, 0, 0]], xs = 0, ys = 3, xd = 2, yd = 2
Output: -1
Explanation: The destination cell (2, 2) cannot be reached from the source cell (0, 3), so the answer is -1.

blobid2_1782119632
Try It Yourself
redirect icon

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.

Working of approach:

  • Start a DFS from the source cell (xs, ys).
  • If the current cell is out of bounds, blocked (0), or already visited, return -1.
  • If the destination cell (xd, yd) is reached, return 0.
  • Mark the current cell as visited to avoid revisiting it in the current path.
  • Explore all four possible directions: up, down, left, and right.
  • Recursively find the longest path from each valid adjacent cell.
  • If a recursive call returns a valid path (!= -1), update the maximum path length as 1 + returned length.
  • After exploring all directions, backtrack by unmarking the current cell in the visited array so it can be used in other possible paths.
  • Return the maximum path length found from the current cell.
  • If no valid path exists from the source to the destination, return -1; otherwise, return the length of the longest path.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;

//Driver Code Ends

// Function to find the longest path using backtracking
int dfs(vector<vector<int>> &mat, 
                vector<vector<bool>> &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<int>> &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<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)
        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 maxPath

def 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

Output
24

[Optimized Approach] Without Using Extra Space - O(4^(m*n)) Time and O(1) Space

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 <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;

//Driver Code Ends

// Function to find the longest path using backtracking without extra space
int dfs(vector<vector<int>> &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<int>> &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<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)
        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 maxPath

def 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

Output
24
Comment