Longest Possible Route in a Matrix

Last Updated : 17 Nov, 2025

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:

420046962

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).

Try It Yourself
redirect icon

[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 <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