Longest Increasing Path in Matrix (original) (raw)

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 3
4
→**5 6, where each number is strictly greater than the previous and movement is allowed in four directions (up, down, left, right).

2-

Table of Content

[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> &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> &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> &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));

`

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

// 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> &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> &matrix, vector<vector> &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> &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> 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));

`

[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> &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> 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));

`