Problem
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:
Input: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9]
.
Example 2:
Input: nums =
[
[3,4,5],
[3,2,6],
[2,2,1]
]
Output: 4
Explanation: The longest increasing path is [3, 4, 5, 6]
. Moving diagonally is not allowed.
Solution1: DFS + Memorization
Time complexity: O(mn)
Space complexity: O(mn)
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Author: Huahua // Running time: 36 ms class Solution { public: int longestIncreasingPath(vector<vector<int>>& matrix) { if (matrix.empty()) return 0; m_ = matrix.size(); n_ = matrix[0].size(); dp_ = vector<vector<int>>(m_, vector<int>(n_, -1)); int ans = 0; for (int y = 0; y < m_; ++y) for (int x = 0; x < n_; ++x) ans = max(ans, dfs(matrix, x, y)); return ans; } private: int dfs(const vector<vector<int>>& mat, int x, int y) { if (dp_[y][x] != -1) return dp_[y][x]; static int dirs[] = {0, -1, 0, 1, 0}; dp_[y][x] = 1; for (int i = 0; i < 4; ++i) { int tx = x + dirs[i]; int ty = y + dirs[i + 1]; if (tx < 0 || ty < 0 || tx >= n_ || ty >= m_ || mat[ty][tx] <= mat[y][x]) continue; dp_[y][x] = max(dp_[y][x], 1 + dfs(mat, tx, ty)); } return dp_[y][x]; } int m_; int n_; // dp[i][j]: max length start from (j, i) vector<vector<int>> dp_; }; |
Solution2: DP
DP
Time complexity: O(mn*log(mn))
Space complexity: O(mn)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Author: Huahua // Running time: 63 ms class Solution { public: int longestIncreasingPath(vector<vector<int>>& matrix) { if (matrix.empty()) return 0; int m = matrix.size(); int n = matrix[0].size(); vector<vector<int>> dp(m, vector<int>(n, 1)); int ans = 0; vector<pair<int, pair<int, int>>> cells; for (int y = 0; y < m; ++y) for (int x = 0; x < n; ++x) cells.push_back({matrix[y][x], {x, y}}); sort(cells.rbegin(), cells.rend()); vector<int> dirs {0, 1, 0, -1, 0}; for (const auto& cell : cells) { int x = cell.second.first; int y = cell.second.second; for (int i = 0; i < 4; ++i) { int tx = x + dirs[i]; int ty = y + dirs[i + 1]; if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue; if (matrix[ty][tx] <= matrix[y][x]) continue; dp[y][x] = max(dp[y][x], 1 + dp[ty][tx]); } ans = max(ans, dp[y][x]); } return ans; } }; |