题目描述
给定一个 m x n 的整数矩阵 matrix,找出其中最长递增路径的长度。
对于每个单元格,你可以往上、下、左、右四个方向移动。不能 在对角线 方向上移动,也不能 移动到边界外 ,并且不能 走重复的单元格。路径必须是严格递增的。
输入描述
-
第一行:两个整数
m和n,表示矩阵的行数和列数(1 <= m, n <= 200)。 -
接下来
m行:每行n个整数,表示矩阵元素(-10^4 <= matrix[i][j] <= 10^4)。
输出描述
一个整数,表示最长递增路径的长度。
示例
输入:
text
3 3
9 9 4
6 6 8
2 1 1
输出:
text
4
说明: 最长递增路径为 1 -> 2 -> 6 -> 9(或 1 -> 2 -> 6 -> 8),长度为 4。
输入:
text
1 1
5
输出:
text
1
输入:
text
2 3
3 4 5
3 2 6
输出:
text
4
说明: 最长递增路径为 3 -> 4 -> 5 -> 6。
方法一:DFS + 记忆化搜索(推荐)
思路: 从每个单元格出发做 DFS,向四个方向探索,只走向比当前值大的相邻单元格。用 memo[i][j] 记录以 (i, j) 为起点的最长递增路径长度,避免重复计算。
-
如果
memo[i][j] != 0,直接返回缓存值。 -
否则,遍历四个方向,对满足
matrix[ni][nj] > matrix[i][j]的邻居递归求解,取最大值 + 1。 -
最终答案是所有单元格中的最大值。
时间复杂度 O(m * n)(每个单元格最多计算一次),空间复杂度 O(m * n)(记忆化数组 + 递归栈)。
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int m, n;
vector<vector<int>> memo;
int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int longestIncreasingPath(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix[0].empty()) return 0;
m = matrix.size();
n = matrix[0].size();
memo.assign(m, vector<int>(n, 0));
int ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
ans = max(ans, dfs(matrix, i, j));
}
}
return ans;
}
private:
int dfs(vector<vector<int>>& matrix, int i, int j) {
if (memo[i][j] != 0) return memo[i][j];
int best = 1; // 至少包含自己
for (auto& d : dirs) {
int ni = i + d[0];
int nj = j + d[1];
if (ni >= 0 && ni < m && nj >= 0 && nj < n &&
matrix[ni][nj] > matrix[i][j]) {
best = max(best, 1 + dfs(matrix, ni, nj));
}
}
memo[i][j] = best;
return best;
}
};
int main() {
int m, n;
cin >> m >> n;
vector<vector<int>> matrix(m, vector<int>(n));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
Solution sol;
cout << sol.longestIncreasingPath(matrix) << endl;
return 0;
}