Open In App

Longest Increasing Path in Matrix

Last Updated : 08 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a matrix with n rows and m columns. The task is to find the length of the longest increasing path in the matrix, here increasing path means that the value in the specified path increases. For example, if a path of length k has values a1, a2, a3, .... ak, then for every i from [2,k] this condition must hold ai > ai-1. No cell should be revisited in the path.

From each cell, we can either move in four directions: left, right, up, or down. We are not allowed to move diagonally or move outside the boundary.

Examples: 

Input: matrix[][] = [[1 2 3],
[4 5 6],
[7 8 9]]
Output: 5
Explanation: One such path is 1 → 2 → 3 → 6 → 9, where each number is strictly greater than the previous and movement is allowed in four directions (up, down, left, right).

1-

Input: matrix[][] = [[3 4 5],
[6 2 6],
[2 2 1]]
Output: 4
Explanation: The longest increasing path is 345 →6, where each number is strictly greater than the previous and movement is allowed in four directions (up, down, left, right).

2-

[Naive Approach] Using Recursion - O(4^(m*n)) Time and O(m*n) Space

The idea is to recursively check the longest paths from each cell. For each cell, initialize the answer to 1. Recursively process all the four directions (first check if the cells are valid and then check that their value is greater than current cell value) and set answer to the maximum of the four directions. Return the calculated answer.

C++
// Recursive c++ program to find
// longest incresing path in matrix
#include <bits/stdc++.h>
using namespace std;

// Function which checks if the cell is valid
// and its value is greater than previous cell.
bool validCell(int i, int j, vector<vector<int>> &matrix, 
               int n, int m, int prev) {
    if (i >= 0 && i < n && j >= 0 && j < m && matrix[i][j] > prev)
        return true;
    return false;
}

int pathRecur(int i, int j, vector<vector<int>> &matrix, 
              int n, int m) {

    // include current cell in answer
    int ans = 1;

    // direction vector to move in 4 directions
    vector<vector<int>> dir = 
    {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    for (auto d : dir) {
        int x = i + d[0], y = j + d[1];

        if (validCell(x, y, matrix, n, m, matrix[i][j])) {
            ans = max(ans, 1 + pathRecur(x, y, matrix, n, m));
        }
    }

    return ans;
}

int longIncPath(vector<vector<int>> &matrix){
    
    int n = matrix.size();
    int m = matrix[0].size();
    int ans = 0;

    // Check longest increasing path
    // for each cell.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            ans = max(ans, pathRecur(i, j, matrix, n, m));
        }
    }

    return ans;
}

int main() {
 
    vector<vector<int>> matrix = 
    {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    cout << longIncPath(matrix) << endl;

    return 0;
}
Java
// Java program to find
// longest increasing path in matrix

import java.util.*;

class GfG {

    // Function which checks if the cell is valid
    // and its value is greater than previous cell.
    static boolean validCell(int i, int j, int[][] matrix,
                             int n, int m, int prev) {
        return (i >= 0 && i < n && j >= 0 && j < m
                && matrix[i][j] > prev);
    }

    static int pathRecur(int i, int j, int[][] matrix,
                         int n, int m) {

        // include current cell in answer
        int ans = 1;

        // direction vectors to move in 4 directions
        int[][] dir
            = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };

        for (int[] d : dir) {
            int x = i + d[0], y = j + d[1];

            // Check if the cell is valid
            if (validCell(x, y, matrix, n, m,
                          matrix[i][j])) {
                ans = Math.max(
                    ans, 1 + pathRecur(x, y, matrix, n, m));
            }
        }

        return ans;
    }

    static int longIncPath(int[][] matrix) {
        int ans = 0;
        int n = matrix.length;
        int m = matrix[0].length;
        // Check longest increasing path
        // for each cell.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans = Math.max(
                    ans, pathRecur(i, j, matrix, n, m));
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int[][] matrix
            = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

        System.out.println(longIncPath(matrix));
    }
}
Python
# Python program to find
# longest increasing path in matrix

def validCell(i, j, matrix, n, m, prev):
    return i >= 0 and i < n and j >= 0 and j < m \
  	and matrix[i][j] > prev


def pathRecur(i, j, matrix, n, m):

    # include current cell in answer
    ans = 1

    # direction vectors to move in 4 directions
    dir = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    for d in dir:
        x, y = i + d[0], j + d[1]

        # Check if the cell is valid
        if validCell(x, y, matrix, n, m, matrix[i][j]):
            ans = max(ans, 1 + pathRecur(x, y, matrix, n, m))

    return ans


def longIncPath(matrix):
    ans = 0
    n = len(matrix)
    m = len(matrix[0])
    # Check longest increasing path
    # for each cell.
    for i in range(n):
        for j in range(m):
            ans = max(ans, pathRecur(i, j, matrix, n, m))

    return ans

if __name__ == "__main__":
  
    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

    print(longIncPath(matrix))
C#
// C# program to find
// longest increasing path in matrix

using System;

class GfG {

    // Function which checks if the cell is valid
    // and its value is greater than previous cell.
    static bool validCell(int i, int j, int[, ] matrix,
                          int n, int m, int prev) {
        return (i >= 0 && i < n && j >= 0 && j < m
                && matrix[i, j] > prev);
    }

    static int pathRecur(int i, int j, int[, ] matrix,
                         int n, int m) {

        // include current cell in answer
        int ans = 1;

        // direction vectors to move in 4 directions
        int[, ] dir
            = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };

        for (int d = 0; d < 4; d++) {
            int x = i + dir[d, 0], y = j + dir[d, 1];

            // Check if the cell is valid
            if (validCell(x, y, matrix, n, m,
                          matrix[i, j])) {
                ans = Math.Max(
                    ans, 1 + pathRecur(x, y, matrix, n, m));
            }
        }

        return ans;
    }

    static int longIncPath(int[, ] matrix) {
        int ans = 0;
        int n = matrix.GetLength(0); 
        int m = matrix.GetLength(1); 
        // Check longest increasing path
        // for each cell.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans = Math.Max(
                    ans, pathRecur(i, j, matrix, n, m));
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int[, ] matrix
            = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

        Console.WriteLine(longIncPath(matrix));
    }
}
JavaScript
// JavaScript program to find
// longest increasing path in matrix

function validCell(i, j, matrix, n, m, prev) {
    return (i >= 0 && i < n && j >= 0 && j < m
            && matrix[i][j] > prev);
}

function pathRecur(i, j, matrix, n, m) {

    // include current cell in answer
    let ans = 1;

    // direction vectors to move in
    // 4 directions
    const dir =
        [ [ 1, 0 ], [ -1, 0 ], [ 0, 1 ], [ 0, -1 ] ];

    for (const d of dir) {
        const x = i + d[0], y = j + d[1];

        // Check if the cell is valid
        if (validCell(x, y, matrix, n, m, matrix[i][j])) {
            ans = Math.max(
                ans, 1 + pathRecur(x, y, matrix, n, m));
        }
    }

    return ans;
}

function longIncPath(matrix) {
    let ans = 0;
    let n = matrix.length;
    let m = matrix[0].length;
    // Check longest increasing path
    // for each cell.
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            ans = Math.max(ans, pathRecur(i, j, matrix, n, m));
        }
    }

    return ans;
}

const matrix = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];

console.log(longIncPath(matrix));

Output
5

[Expected Approach 1] Using Top-Down DP (Memoization) - O(m*n) Time and O(m*n) Space

The idea is to use Dynamic Programming in the first approach. For a given cell, store its result in the 2D array so that if this cell is again called, we can simply return the value stored in the 2D array.

1. Optimal Substructure:
The longest increasing path from a given cell depends on the optimal solutions of its four neighboring cells. By combining these optimal substructures, we can efficiently calculate longest increasing path starting from given cell.

2. Overlapping Subproblems:
We can observe that a cell can be a neighbour of multiple cells and multiple calls can be made for it.

  • There are two parameters: i and j (cell indices) that changes in the recursive solution. So create a 2D array of size n*m (where n is the number of rows and m is the number of columns in the matrix).
  • Initiate all values in the 2D array as -1 to indicate nothing is computed yet.
  • Check the longest increasing path for each cell (i, j). If the value in array for given cell is -1, then only make the recursive calls for the neighboring cells and store the result in the array. Otherwise, simply return the value stored in the array.
C++
// c++ program to find
// longest incresing path in matrix
#include <bits/stdc++.h>
using namespace std;

// Function which checks if the cell is valid
// and its value is greater than previous cell.
bool validCell(int i, int j, vector<vector<int>> &matrix, int prev) {
    if (i >= 0 && i < matrix.size() && j >= 0 && 
        j < matrix[0].size() && matrix[i][j] > prev)
        return true;
    return false;
}

int pathRecur(int i, int j, vector<vector<int>> &matrix, 
              vector<vector<int>> &memo) {

    // If answer exists in memo table.
    if (memo[i][j] != -1)
        return memo[i][j];

    // include current cell in answer
    int ans = 1;

    // direction vector to move in 4 directions
    vector<vector<int>> dir = 
    		{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    for (auto d : dir) {
        int x = i + d[0], y = j + d[1];

        // Check if the cell is valid
        if (validCell(x, y, matrix, matrix[i][j])) {
            ans = max(ans, 1 + pathRecur(x, y, matrix, memo));
        }
    }

    // Memoize the answer and return it.
    return memo[i][j] = ans;
}

int longIncPath(vector<vector<int>> &matrix,
                          int n, int m) {
    int ans = 0;

    // Initialize dp table
    vector<vector<int>> memo(n, vector<int>(m, -1));

    // Check longest increasing path
    // for each cell.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            ans = max(ans, pathRecur(i, j, matrix, memo));
        }
    }

    return ans;
}

int main() {
    int n = 3, m = 3;
    vector<vector<int>> matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    cout << longIncPath(matrix, n, m) << endl;

    return 0;
}
Java
// Java program to find
// longest increasing path in matrix

class GfG {

    // Function which checks if the cell is valid
    // and its value is greater than previous cell.
    static boolean validCell(int i, int j, int[][] matrix,
                             int prev) {
        return (i >= 0 && i < matrix.length && j >= 0
                && j < matrix[0].length
                && matrix[i][j] > prev);
    }

    static int pathRecur(int i, int j, int[][] matrix,
                         int[][] memo) {

        // If answer exists in memo table.
        if (memo[i][j] != -1)
            return memo[i][j];

        // include current cell in answer
        int ans = 1;

        // direction vector to move in 4 directions
        int[][] dir
            = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };

        for (int[] d : dir) {
            int x = i + d[0], y = j + d[1];

            // Check if the cell is valid
            if (validCell(x, y, matrix, matrix[i][j])) {
                ans = Math.max(
                    ans, 1 + pathRecur(x, y, matrix, memo));
            }
        }

        // Memoize the answer and return it.
        memo[i][j] = ans;
        return ans;
    }

    static int longIncPath(int[][] matrix, int n,
                                     int m) {
        int ans = 0;

        // Initialize dp table
        int[][] memo = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                memo[i][j] = -1;
            }
        }

        // Check longest increasing path
        // for each cell.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans = Math.max(
                    ans, pathRecur(i, j, matrix, memo));
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int n = 3, m = 3;
        int[][] matrix
            = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

        System.out.println(longIncPath(matrix, n, m));
    }
}
Python
# Python program to find
# longest increasing path in matrix

def validCell(i, j, matrix, prev):
    return i >= 0 and i < len(matrix) and j >= 0 and\
  	j < len(matrix[0]) and matrix[i][j] > prev


def pathRecur(i, j, matrix, memo):

    # If answer exists in memo table.
    if memo[i][j] != -1:
        return memo[i][j]

    # include current cell in answer
    ans = 1

    # direction vectors to move in
    # 4 directions
    dir = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    for d in dir:
        x, y = i + d[0], j + d[1]

        # Check if the cell is valid
        if validCell(x, y, matrix, matrix[i][j]):
            ans = max(ans, 1 + pathRecur(x, y, matrix, memo))

    # Memoize the answer and return it.
    memo[i][j] = ans
    return ans


def longIncPath(matrix, n, m):
    ans = 0

    # Initialize dp table
    memo = [[-1] * m for _ in range(n)]

    # Check longest increasing path
    # for each cell.
    for i in range(n):
        for j in range(m):
            ans = max(ans, pathRecur(i, j, matrix, memo))

    return ans


if __name__ == "__main__":
    n, m = 3, 3
    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

    print(longIncPath(matrix, n, m))
C#
// C# program to find
// longest increasing path in matrix

using System;

class GfG {

    // Function which checks if the cell is valid
    // and its value is greater than previous cell.
    static bool validCell(int i, int j, int[, ] matrix,
                          int prev) {
        return (i >= 0 && i < matrix.GetLength(0) && j >= 0
                && j < matrix.GetLength(1)
                && matrix[i, j] > prev);
    }

    static int pathRecur(int i, int j, int[, ] matrix,
                         int[, ] memo) {

        // If answer exists in memo table.
        if (memo[i, j] != -1)
            return memo[i, j];

        // include current cell in answer
        int ans = 1;

        // direction vectors to move in 4 directions
        int[, ] dir
            = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };

        for (int d = 0; d < 4; d++) {
            int x = i + dir[d, 0], y = j + dir[d, 1];

            // Check if the cell is valid
            if (validCell(x, y, matrix, matrix[i, j])) {
                ans = Math.Max(
                    ans, 1 + pathRecur(x, y, matrix, memo));
            }
        }

        // Memoize the answer
      	// and return it.
        memo[i, j] = ans;
        return ans;
    }

    static int longIncPath(int[, ] matrix, int n, int m) {
        int ans = 0;

        // Initialize dp table
        int[, ] memo = new int[n, m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                memo[i, j] = -1;
            }
        }

        // Check longest increasing path
        // for each cell.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans = Math.Max(
                    ans, pathRecur(i, j, matrix, memo));
            }
        }

        return ans;
    }

    static void Main(string[] args) {
        int n = 3, m = 3;
        int[, ] matrix
            = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

        Console.WriteLine(longIncPath(matrix, n, m));
    }
}
JavaScript
// JavaScript program to find
// longest increasing path in matrix

function validCell(i, j, matrix, prev) {
    return i >= 0 && i < matrix.length && j >= 0
           && j < matrix[0].length && matrix[i][j] > prev;
}

function pathRecur(i, j, matrix, memo) {

    // If answer exists in memo table.
    if (memo[i][j] !== -1)
        return memo[i][j];

    // include current cell in answer
    let ans = 1;

    // direction vectors to move in 4 directions
    const dir =
        [ [ 1, 0 ], [ -1, 0 ], [ 0, 1 ], [ 0, -1 ] ];

    for (const d of dir) {
        const x = i + d[0], y = j + d[1];

        // Check if the cell is valid
        if (validCell(x, y, matrix, matrix[i][j])) {
            ans = Math.max(
                ans, 1 + pathRecur(x, y, matrix, memo));
        }
    }

    // Memoize the answer and return it.
    memo[i][j] = ans;
    return ans;
}

function longIncPath(matrix, n, m) {

    let ans = 0;

    // Initialize dp table
    const memo
        = Array.from({length : n}, 
        			() => Array(m).fill(-1));

    // Check longest increasing path
    // for each cell.
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            ans = Math.max(ans,
                           pathRecur(i, j, matrix, memo));
        }
    }

    return ans;
}

const n = 3, m = 3;
const matrix = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];

console.log(longIncPath(matrix, n, m));

Output
5

[Expected Approach 2] Using Kahn's algorithm - O(m*n) Time and O(n*m) Space

Each cell in the matrix is treated as a node, and there's a directed edge from a cell to its neighboring cell if the neighbor has a greater value. The graph formed this way is a directed acyclic graph and this problem reduces to longest path in a directed acyclic graph. We can find the longest path using Topological Sorting. We have used Kahn's algorithm in the below implementation.

To implement Kahn's algorithm, we first compute the in-degree of each cell (i.e., the number of smaller neighbors pointing into it), which helps identify the starting points of increasing paths (cells with in-degree 0). These starting cells are enqueued, and we perform a level-order traversal (BFS), where each level represents one step further in the increasing sequence. For each cell we process, we update the in-degree of its larger neighbors, and if their in-degree becomes 0, we enqueue them as they are ready to be part of the path. The number of BFS levels we process gives us the maximum path length.

C++
// C++ program to find the longest increasing path in a matrix using BFS (Topological Sort)
#include <bits/stdc++.h>
using namespace std;

// Function to find the longest increasing path in a matrix
int longIncPath(vector<vector<int>> &matrix) {
    
    int n = matrix.size();        
    int m = matrix[0].size();     
    
    // Direction vectors for moving right, down, left, and up
    vector<pair<int, int>> dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    // Create an in-degree matrix (used to count number
    // of smaller neighbors for each cell)
    vector<vector<int>> degree(n + 1, vector<int>(m + 1, 0));

    // Compute the in-degree for each cell
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (auto it : dir) {
                int x = i + it.first;
                int y = j + it.second;

                // If neighboring cell is within bounds 
                // and has a smaller value
                if (x >= 0 && x < n && y >= 0 && y < m &&
                    matrix[x][y] < matrix[i][j])
                    degree[i][j]++;  // Increase in-degree count
            }
        }
    }

    // Add all cells with in-degree 0 to the 
    // queue (they are starting points)
    queue<pair<int, int>> q;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (degree[i][j] == 0)
                q.push({i, j});

    int ans = 0;  // This will count the number
                  // of levels processed (i.e., 
                  // length of path)

    // Perform BFS level-by-level
    while (!q.empty()) {
        ans++;                
        int l = q.size();     
        
        for (int i = 0; i < l; i++) {
            int x1 = q.front().first;
            int y1 = q.front().second;
            q.pop();

            // Explore all four directions
            for (auto it : dir) {
                int x = x1 + it.first;
                int y = y1 + it.second;

                // If neighboring cell has greater 
                // value (valid increasing move)
                if (x >= 0 && x < n && y >= 0 && y < m && 
                    matrix[x][y] > matrix[x1][y1]) {
                    degree[x][y]--;  
                    if (degree[x][y] == 0) {
                        q.push({x, y});  
                    }
                }
            }
        }
    }

    // Return the total number of BFS levels = length
    // of the longest increasing path
    return ans;
}

int main() {
    vector<vector<int>> matrix = {{1, 2, 3},
                                  {4, 5, 6},
                                  {7, 8, 9}};
    cout << longIncPath(matrix) << endl;
    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to find the longest increasing path in a matrix
    static int longIncPath(int[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;

        // Direction vectors: right, down, left, up
        int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

        // In-degree matrix
        int[][] degree = new int[n][m];

        // Compute in-degrees
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int[] d : dir) {
                    int x = i + d[0];
                    int y = j + d[1];

                    if (x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] < matrix[i][j]) {
                        degree[i][j]++;
                    }
                }
            }
        }

        // Enqueue all 0 in-degree cells
        Queue<int[]> q = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (degree[i][j] == 0) {
                    q.offer(new int[]{i, j});
                }
            }
        }

        int ans = 0;

        // BFS level-by-level
        while (!q.isEmpty()) {
            ans++;
            int size = q.size();

            for (int i = 0; i < size; i++) {
                int[] cell = q.poll();
                int x1 = cell[0], y1 = cell[1];

                for (int[] d : dir) {
                    int x = x1 + d[0];
                    int y = y1 + d[1];

                    if (x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] > matrix[x1][y1]) {
                        degree[x][y]--;
                        if (degree[x][y] == 0) {
                            q.offer(new int[]{x, y});
                        }
                    }
                }
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };

        System.out.println(longIncPath(matrix));
    }
}
Python
from collections import deque

# Function to find the longest increasing path in a matrix
def longIncPath(matrix):
    n = len(matrix)
    m = len(matrix[0])

    # Direction vectors: right, down, left, up
    dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]

    # In-degree matrix
    degree = [[0 for _ in range(m)] for _ in range(n)]

    # Compute in-degrees
    for i in range(n):
        for j in range(m):
            for dx, dy in dir:
                x, y = i + dx, j + dy
                if 0 <= x < n and 0 <= y < m and matrix[x][y] < matrix[i][j]:
                    degree[i][j] += 1

    # Enqueue all 0 in-degree cells
    q = deque()
    for i in range(n):
        for j in range(m):
            if degree[i][j] == 0:
                q.append((i, j))

    # BFS level-by-level
    ans = 0
    while q:
        ans += 1
        for _ in range(len(q)):
            x1, y1 = q.popleft()
            for dx, dy in dir:
                x, y = x1 + dx, y1 + dy
                if 0 <= x < n and 0 <= y < m and matrix[x][y] > matrix[x1][y1]:
                    degree[x][y] -= 1
                    if degree[x][y] == 0:
                        q.append((x, y))
    return ans

# Example usage
if __name__ == "__main__": 
    matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
    ]
    print(longIncPath(matrix))
C#
using System;
using System.Collections.Generic;

class GfG{

    // Function to find the longest increasing path in a matrix
    static int longIncPath(int[,] matrix) {
        int n = matrix.GetLength(0);
        int m = matrix.GetLength(1);

        // Direction vectors: right, down, left, up
        int[,] dir = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };

        // In-degree matrix
        int[,] degree = new int[n, m];

        // Step 1: Compute in-degrees
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int d = 0; d < 4; d++) {
                    int x = i + dir[d, 0];
                    int y = j + dir[d, 1];

                    if (x >= 0 && x < n && y >= 0 && y < m && matrix[x, y] < matrix[i, j]) {
                        degree[i, j]++;
                    }
                }
            }
        }

        // Step 2: Enqueue all 0 in-degree cells
        Queue<(int, int)> q = new Queue<(int, int)>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (degree[i, j] == 0) {
                    q.Enqueue((i, j));
                }
            }
        }

        int ans = 0;

        // Step 3: BFS level-by-level
        while (q.Count > 0) {
            ans++;
            int size = q.Count;

            for (int i = 0; i < size; i++) {
                var (x1, y1) = q.Dequeue();

                for (int d = 0; d < 4; d++) {
                    int x = x1 + dir[d, 0];
                    int y = y1 + dir[d, 1];

                    if (x >= 0 && x < n && y >= 0 && y < m && matrix[x, y] > matrix[x1, y1]) {
                        degree[x, y]--;
                        if (degree[x, y] == 0) {
                            q.Enqueue((x, y));
                        }
                    }
                }
            }
        }

        return ans;
    }

    static void Main() {
        int[,] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };

        Console.WriteLine(longIncPath(matrix));
    }
}
JavaScript
// Function to find the longest increasing path in a matrix
function longIncPath(matrix) {
    const n = matrix.length;
    const m = matrix[0].length;

    // Direction vectors: right, down, left, up
    const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]];

    // In-degree matrix
    const degree = Array.from({ length: n }, () => Array(m).fill(0));

    // Compute in-degrees
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            for (const [dx, dy] of dir) {
                const x = i + dx;
                const y = j + dy;
                if (x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] < matrix[i][j]) {
                    degree[i][j]++;
                }
            }
        }
    }

    // Enqueue all 0 in-degree cells
    const q = [];
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (degree[i][j] === 0) {
                q.push([i, j]);
            }
        }
    }

    //  BFS level-by-level
    let ans = 0;
    while (q.length > 0) {
        ans++;
        const size = q.length;
        for (let i = 0; i < size; i++) {
            const [x1, y1] = q.shift();
            for (const [dx, dy] of dir) {
                const x = x1 + dx;
                const y = y1 + dy;
                if (x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] > matrix[x1][y1]) {
                    degree[x][y]--;
                    if (degree[x][y] === 0) {
                        q.push([x, y]);
                    }
                }
            }
        }
    }

    return ans;
}

// Driver Code
const matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];
console.log(longIncPath(matrix));

Output
5

Similar Reads