Find the longest path in a matrix with given constraints

28 Jun, 2022
Given a n*n matrix where all numbers are distinct, find the maximum length path (starting from any cell) such that all cells along the path are in increasing order with a difference of 1. We can move in 4 directions from a given cell (i, j), i.e., we can move to (i+1, j) or (i, j+1) or (i-1, j) or (i, j-1) with the condition that the adjacent cells have a difference of 1.
Example: 
Input:  mat[][] = {{1, 2, 9}
                   {5, 3, 8}
                   {4, 6, 7}}
Output: 4
The longest path is 6-7-8-9. 
The idea is simple, we calculate longest path beginning with every cell. Once we have computed longest for all cells, we return maximum of all longest paths. One important observation in this approach is many overlapping sub-problems. Therefore this problem can be optimally solved using Dynamic Programming. 
Below is Dynamic Programming based implementation that uses a lookup table dp[][] to check if a problem is already solved or not.
C++
Java
Python3
Javascript
C#
// C++ program to find the longest path in a matrix// with given constraints#include <bits/stdc++.h>#define n 3using namespace std; // Returns length of the longest path beginning with// mat[i][j]. This function mainly uses lookup table// dp[n][n]int findLongestFromACell(int i, int j, int mat[n][n],                         int dp[n][n]){    if (i < 0 || i >= n || j < 0 || j >= n)        return 0;     // If this subproblem is already solved    if (dp[i][j] != -1)        return dp[i][j];     // To store the path lengths in all the four directions    int x = INT_MIN, y = INT_MIN, z = INT_MIN, w = INT_MIN;     // Since all numbers are unique and in range from 1 to    // n*n, there is atmost one possible direction from any    // cell    if (j < n - 1 && ((mat[i][j] + 1) == mat[i][j + 1]))        x = 1 + findLongestFromACell(i, j + 1, mat, dp);     if (j > 0 && (mat[i][j] + 1 == mat[i][j - 1]))        y = 1 + findLongestFromACell(i, j - 1, mat, dp);     if (i > 0 && (mat[i][j] + 1 == mat[i - 1][j]))        z = 1 + findLongestFromACell(i - 1, j, mat, dp);     if (i < n - 1 && (mat[i][j] + 1 == mat[i + 1][j]))        w = 1 + findLongestFromACell(i + 1, j, mat, dp);     // If none of the adjacent fours is one greater we will    // take 1 otherwise we will pick maximum from all the    // four directions    return dp[i][j] = max({x, y, z, w, 1});} // Returns length of the longest path beginning with any// cellint finLongestOverAll(int mat[n][n]){    int result = 1; // Initialize result     // Create a lookup table and fill all entries in it as    // -1    int dp[n][n];    memset(dp, -1, sizeof dp);     // Compute longest path beginning from all cells    for (int i = 0; i < n; i++) {        for (int j = 0; j < n; j++) {            if (dp[i][j] == -1)                findLongestFromACell(i, j, mat, dp);             // Update result if needed            result = max(result, dp[i][j]);        }    }     return result;} // Driver programint main(){    int mat[n][n]        = { { 1, 2, 9 }, { 5, 3, 8 }, { 4, 6, 7 } };    cout << "Length of the longest path is "         << finLongestOverAll(mat);    return 0;}
// Java program to find the longest path in a matrix// with given constraints class GFG {    public static int n = 3;     // Function that returns length of the longest path    // beginning with mat[i][j]    // This function mainly uses lookup table dp[n][n]    static int findLongestFromACell(int i, int j,                                    int mat[][], int dp[][])    {        // Base case        if (i < 0 || i >= n || j < 0 || j >= n)            return 0;         // If this subproblem is already solved        if (dp[i][j] != -1)            return dp[i][j];         // To store the path lengths in all the four        // directions        int x = Integer.MIN_VALUE, y = Integer.MIN_VALUE,            z = Integer.MIN_VALUE, w = Integer.MIN_VALUE;        // Since all numbers are unique and in range from 1        // to n*n, there is atmost one possible direction        // from any cell        if (j < n - 1 && ((mat[i][j] + 1) == mat[i][j + 1]))            x = dp[i][j]                = 1                  + findLongestFromACell(i, j + 1, mat, dp);         if (j > 0 && (mat[i][j] + 1 == mat[i][j - 1]))            y = dp[i][j]                = 1                  + findLongestFromACell(i, j - 1, mat, dp);         if (i > 0 && (mat[i][j] + 1 == mat[i - 1][j]))            z = dp[i][j]                = 1                  + findLongestFromACell(i - 1, j, mat, dp);         if (i < n - 1 && (mat[i][j] + 1 == mat[i + 1][j]))            w = dp[i][j]                = 1                  + findLongestFromACell(i + 1, j, mat, dp);         // If none of the adjacent fours is one greater we        // will take 1 otherwise we will pick maximum from        // all the four directions        return dp[i][j]            = Math.max(                x,                Math.max(y, Math.max(z, Math.max(w, 1))));    }     // Function that returns length of the longest path    // beginning with any cell    static int finLongestOverAll(int mat[][])    {        // Initialize result        int result = 1;         // Create a lookup table and fill all entries in it        // as -1        int[][] dp = new int[n][n];        for (int i = 0; i < n; i++)            for (int j = 0; j < n; j++)                dp[i][j] = -1;         // Compute longest path beginning from all cells        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                if (dp[i][j] == -1)                    findLongestFromACell(i, j, mat, dp);                 // Update result if needed                result = Math.max(result, dp[i][j]);            }        }         return result;    }     // driver program    public static void main(String[] args)    {        int mat[][]            = { { 1, 2, 9 }, { 5, 3, 8 }, { 4, 6, 7 } };        System.out.println("Length of the longest path is "                           + finLongestOverAll(mat));    }} // Contributed by Pramod Kumar
# Python3 program to find the longest path in a matrix# with given constraints n = 3# Returns length of the longest path beginning with mat[i][j].# This function mainly uses lookup table dp[n][n]  def findLongestFromACell(i, j, mat, dp):    # Base case    if (i < 0 or i >= n or j < 0 or j >= n):        return 0     # If this subproblem is already solved    if (dp[i][j] != -1):        return dp[i][j]     # To store the path lengths in all the four directions    x, y, z, w = -1, -1, -1, -1     # Since all numbers are unique and in range from 1 to n * n,    # there is atmost one possible direction from any cell    if (j < n-1 and ((mat[i][j] + 1) == mat[i][j + 1])):        x = 1 + findLongestFromACell(i, j + 1, mat, dp)     if (j > 0 and (mat[i][j] + 1 == mat[i][j-1])):        y = 1 + findLongestFromACell(i, j-1, mat, dp)     if (i > 0 and (mat[i][j] + 1 == mat[i-1][j])):        z = 1 + findLongestFromACell(i-1, j, mat, dp)     if (i < n-1 and (mat[i][j] + 1 == mat[i + 1][j])):        w = 1 + findLongestFromACell(i + 1, j, mat, dp)     # If none of the adjacent fours is one greater we will take 1    # otherwise we will pick maximum from all the four directions    dp[i][j] = max(x, max(y, max(z, max(w, 1))))    return dp[i][j]  # Returns length of the longest path beginning with any celldef finLongestOverAll(mat):    result = 1  # Initialize result     # Create a lookup table and fill all entries in it as -1    dp = [[-1 for i in range(n)]for i in range(n)]     # Compute longest path beginning from all cells    for i in range(n):        for j in range(n):            if (dp[i][j] == -1):                findLongestFromACell(i, j, mat, dp)            # Update result if needed            result = max(result, dp[i][j])    return result  # Driver programmat = [[1, 2, 9],       [5, 3, 8],       [4, 6, 7]]print("Length of the longest path is ", finLongestOverAll(mat)) # this code is improved by sahilshelangia
<script>// JavaScript program to find the longest path in a matrix// with given constraintslet n = 3; // Returns length of the longest path beginning with mat[i][j].// This function mainly uses lookup table dp[n][n]function findLongestFromACell( i, j, mat, dp){    if (i < 0 || i >= n || j < 0 || j >= n)        return 0;     // If this subproblem is already solved    if (dp[i][j] != -1)        return dp[i][j];     // To store the path lengths in all the four directions         let x,y,z,w;    x = -1;    y = -1;    z = -1    w = -1;     // Since all numbers are unique and in range from 1 to n*n,    // there is atmost one possible direction from any cell    if (j < n - 1 && ((mat[i][j] + 1) == mat[i][j + 1]))        x = 1 + findLongestFromACell(i, j + 1, mat, dp);     if (j > 0 && (mat[i][j] + 1 == mat[i][j - 1]))        y = 1 + findLongestFromACell(i, j - 1, mat, dp);     if (i > 0 && (mat[i][j] + 1 == mat[i - 1][j]))        z = 1 + findLongestFromACell(i - 1, j, mat, dp);     if (i < n - 1 && (mat[i][j] + 1 == mat[i + 1][j]))        w = 1 + findLongestFromACell(i + 1, j, mat, dp);     // If none of the adjacent fours is one greater we will take 1    // otherwise we will pick maximum from all the four directions    dp[i][j] = Math.max(x, Math.max(y, Math.max(z, Math.max(w, 1))));    return dp[i][j];} // Returns length of the longest path beginning with any cellfunction finLongestOverAll( mat){    let result = 1; // Initialize result     // Create a lookup table and fill all entries in it as -1    var dp = [];      for( var y = 0; y < n; y++ ) {    dp[ y ] = [];    for( var x = 0; x < n; x++ ) {        dp[ y ][ x ] = -1;    }}     // Compute longest path beginning from all cells    for (let i = 0; i < n; i++) {        for (let j = 0; j < n; j++) {            if (dp[i][j] == -1)                findLongestFromACell(i, j, mat, dp);             // Update result if needed            result = Math.max(result, dp[i][j]);        }    }     return result;} // Driver programlet mat = [[ 1, 2, 9 ],            [ 5, 3, 8 ],            [ 4, 6, 7 ]]; document.write("Length of the longest path is ");document.write( finLongestOverAll(mat)); </script>
// C# program to find the longest path// in a matrix with given constraintsusing System; class GFG {    public static int n = 3;     // Function that returns length of    // the longest path beginning with mat[i][j]    // This function mainly uses lookup    // table dp[n][n]    public static int findLongestFromACell(int i, int j,                                           int[][] mat,                                           int[][] dp)    {        // Base case        if (i < 0 || i >= n || j < 0 || j >= n) {            return 0;        }         // If this subproblem is        // already solved        if (dp[i][j] != -1) {            return dp[i][j];        }         // To store the path lengths in all the four        // directions        int x = int.MinValue, y = int.MinValue,            z = int.MinValue, w = int.MinValue;         // Since all numbers are unique and        // in range from 1 to n*n, there is        // atmost one possible direction        // from any cell        if (j < n - 1            && ((mat[i][j] + 1) == mat[i][j + 1])) {            x = dp[i][j]                = 1                  + findLongestFromACell(i, j + 1, mat, dp);        }         if (j > 0 && (mat[i][j] + 1 == mat[i][j - 1])) {            y = dp[i][j]                = 1                  + findLongestFromACell(i, j - 1, mat, dp);        }         if (i > 0 && (mat[i][j] + 1 == mat[i - 1][j])) {            z = dp[i][j]                = 1                  + findLongestFromACell(i - 1, j, mat, dp);        }         if (i < n - 1 && (mat[i][j] + 1 == mat[i + 1][j])) {            w = dp[i][j]                = 1                  + findLongestFromACell(i + 1, j, mat, dp);        }         // If none of the adjacent fours is one greater we        // will take 1 otherwise we will pick maximum from        // all the four directions        dp[i][j] = Math.Max(            x, Math.Max(y, Math.Max(z, Math.Max(w, 1))));        return dp[i][j];    }     // Function that returns length of the    // longest path beginning with any cell    public static int finLongestOverAll(int[][] mat)    {        // Initialize result        int result = 1;         // Create a lookup table and fill        // all entries in it as -1        int[][] dp            = RectangularArrays.ReturnRectangularIntArray(                n, n);        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                dp[i][j] = -1;            }        }         // Compute longest path beginning        // from all cells        for (int i = 0; i < n; i++) {            for (int j = 0; j < n; j++) {                if (dp[i][j] == -1) {                    findLongestFromACell(i, j, mat, dp);                }                 // Update result if needed                result = Math.Max(result, dp[i][j]);            }        }         return result;    }     public static class RectangularArrays {        public static int[][] ReturnRectangularIntArray(            int size1, int size2)        {            int[][] newArray = new int[size1][];            for (int array1 = 0; array1 < size1; array1++) {                newArray[array1] = new int[size2];            }             return newArray;        }    }     // Driver Code    public static void Main(string[] args)    {        int[][] mat = new int[][] { new int[] { 1, 2, 9 },                                    new int[] { 5, 3, 8 },                                    new int[] { 4, 6, 7 } };        Console.WriteLine("Length of the longest path is "                          + finLongestOverAll(mat));    }} // This code is contributed by Shrikant13
Length of the longest path is 4
Time complexity of the above solution is O(n2). It may seem more at first look. If we take a closer look, we can notice that all values of dp[i][j] are computed only once.Auxiliary Space: O(N x N),
This article is contributed by Aarti_Rathi and Ekta Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
sahilshelangia
shrikanth13
MOHNEESHGARG
gp6
Jaspreet Singh
rohitsingh07052
atharvakango
sksusha8853
codewithshinchan
hardikkoriintern
Amazon
Samsung
Dynamic Programming
Matrix
Amazon
Samsung
Dynamic Programming
Matrix
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Largest Sum Contiguous Subarray
Program for Fibonacci numbers
Longest Palindromic Substring | Set 1
Longest Increasing Subsequence | DP-3
Find if there is a path between two vertices in an undirected graph
Print a given matrix in spiral form
Program to find largest element in an array
Rat in a Maze | Backtracking-2
Sudoku | Backtracking-7
Find the number of islands | Set 1 (Using DFS)