✨题目链接:
NC138 矩阵最长递增路径
✨题目描述
给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。
这个路径必须满足以下条件:
1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。
2. 你不能走重复的单元格。即每个格子最多只能走一次。
数据范围:1≤𝑛,𝑚≤10001≤n,m≤1000,0≤𝑚𝑎𝑡𝑟𝑖𝑥[𝑖][𝑗]≤10000≤matrix[i][j]≤1000
进阶:空间复杂度 𝑂(𝑛𝑚)O(nm) ,时间复杂度 𝑂(𝑛𝑚)O(nm)
例如:当输入为[[1,2,3],[4,5,6],[7,8,9]]时,对应的输出为5,
其中的一条最长递增路径如下图所示:
✨示例1
📍输入
[[1,2,3],[4,5,6],[7,8,9]]
📍输出
5
📍说明
1->2->3->6->9即可。当然这种递增路径不是唯一的。
✨示例2
📍输入
[[1,2],[4,3]]
📍输出
4
📍说明
1->2->3->4
✨解题思路
-
深度优先搜索(DFS)与记忆化搜索:通过DFS遍历矩阵的每个单元格,从每个单元格开始搜索最长的递增路径。使用记忆化搜索(Memoization)来存储每个单元格开始的最长路径,避免重复计算。
-
方向数组:使用一个方向数组来简化移动操作。方向数组包括四个方向:上、下、左、右。
-
辅助矩阵(dp):创建一个与输入矩阵相同大小的辅助矩阵
dp
,用于存储从每个单元格开始的最长递增路径长度。
具体实现步骤
-
输入处理:
- 读取矩阵的行数
n
和列数m
。 - 读取矩阵的数据,并存储在二维向量
matrix
中。
- 读取矩阵的行数
-
初始化:
- 初始化一个与输入矩阵同样大小的
dp
矩阵,初始值为-1,表示尚未计算该单元格的最长路径长度。
- 初始化一个与输入矩阵同样大小的
-
深度优先搜索(DFS):
- 对于每个单元格
(i, j)
,如果dp[i][j]
已经计算过(不等于-1),则直接返回dp[i][j]
的值。 - 否则,从该单元格出发,尝试向四个方向移动。如果移动后的位置值大于当前值,则递归调用DFS,并更新最长路径长度。
- 更新
dp[i][j]
为从该单元格开始的最长路径长度。
- 对于每个单元格
-
遍历矩阵:
- 遍历矩阵中的每个单元格,调用DFS函数计算从该单元格开始的最长路径,并更新全局最长路径长度。
-
输出结果:
- 输出矩阵中最长递增路径的长度。
✨代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int solve(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix[0].empty()) {
return 0;
}
n = matrix.size();
m = matrix[0].size();
dp = vector<vector<int>>(n, vector<int>(m, -1));
this->matrix = matrix;
longestPath = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
longestPath = max(longestPath, dfs(i, j));
}
}
return longestPath;
}
private:
int n, m;
vector<vector<int>> dp;
vector<vector<int>> matrix;
int longestPath;
vector<int> directions = {-1, 0, 1, 0, -1}; // 用于上下左右移动
int dfs(int x, int y) {
if (dp[x][y] != -1) {
return dp[x][y];
}
int maxLen = 1;
for (int i = 0; i < 4; ++i) {
int nx = x + directions[i];
int ny = y + directions[i + 1];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && matrix[nx][ny] > matrix[x][y]) {
maxLen = max(maxLen, 1 + dfs(nx, ny));
}
}
dp[x][y] = maxLen;
return dp[x][y];
}
};
※ 如果文章对你有帮助的话,可以点赞收藏!!谢谢支持