Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Given an integer matrix, find the length of the longest increasing path.

From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

Example 1:

nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]

Return 4 The longest increasing path is [1, 2, 6, 9].

Example 2:

nums = [
  [3,4,5],
  [3,2,6],
  [2,2,1]
]

Return 4 The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.

Solution 1. DFS

Typical DFS. Use a vector<vector<int>> cnt, where cnt[i][j] is the length of longest increasing path starting from matrix[i][j]. Initially values in cnt are all zeroes.

For each position matrix[x][y],

  • if cnt[x][y] is not zero, which means it's already visited, return cnt[x][y] right away.
  • otherwise, probe the 4 directions, cnt[x][y] is one greater than its largest neightbor.
// OJ: https://leetcode.com/problems/longest-increasing-path-in-a-matrix/
// Author: github.com/lzl124631x
// Time: O(MN)
// Space: O(MN)
class Solution {
    vector<vector<int>> cnt;
    int ans = 0, M, N, dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
    int dfs(vector<vector<int>> &A, int x, int y) {
        if (cnt[x][y]) return cnt[x][y];
        cnt[x][y] = 1;
        for (auto &dir : dirs) {
            int a = x + dir[0], b = y + dir[1];
            if (a < 0 || b < 0 || a >= M || b >= N || A[a][b] <= A[x][y]) continue;
            cnt[x][y] = max(cnt[x][y], 1 + dfs(A, a, b));
        }
        return cnt[x][y];
    }
public:
    int longestIncreasingPath(vector<vector<int>>& A) {
        if (A.empty() || A[0].empty()) return 0;
        M = A.size(), N = A[0].size();
        cnt.assign(M, vector<int>(N));
        for (int i = 0; i < M; ++i) 
            for (int j = 0; j < N; ++j) 
                ans = max(ans, dfs(A, i, j));
        return ans;
    }
};

Solution 2. Topological Sort (BFS)

Note that the DFS version of topological sort solution is the same as the Solution 1.

// OJ: https://leetcode.com/problems/longest-increasing-path-in-a-matrix/
// Author: github.com/lzl124631x
// Time: O(MN)
// Space: O(MN)
// Ref: https://leetcode.com/problems/longest-increasing-path-in-a-matrix/discuss/288520/BFS-Implemented-Topological-Sort
class Solution {
public:
    int longestIncreasingPath(vector<vector<int>>& A) {
        if (A.empty() || A[0].empty()) return 0;
        int M = A.size(), N = A[0].size(), ans = 0, dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
        vector<vector<int>> indegree(M, vector<int>(N));
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                for (auto &dir : dirs) {
                    int x = i + dir[0], y = j + dir[1];
                    if (x < 0 || x >= M || y < 0 || y >= N || A[x][y] <= A[i][j]) continue;
                    indegree[x][y]++;
                }
            }
        }
        queue<vector<int>> q;
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                if (indegree[i][j] == 0) q.push({ i, j });
            }
        }
        while (q.size()) {
            int sz = q.size();
            while (sz--) {
                int x = q.front()[0], y = q.front()[1];
                q.pop();
                for (auto &dir : dirs) {
                    int a = x + dir[0], b = y + dir[1];
                    if (a < 0 || a >= M || b < 0 || b >= N || A[a][b] <= A[x][y]) continue;
                    if (--indegree[a][b] == 0) q.push({ a, b });
                }
            }
            ++ans;
        }
        return ans;
    }
};