阿犇

记录生活中的点点滴滴

0%

最长递增路径

Trace

剑指 Offer II 112. 最长递增路径

传送门:https://leetcode-cn.com/problems/fpTFWP/

Problem

给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。

对于每个单元格,你可以往上,下,左,右四个方向移动。 不能对角线 方向上移动或移动到 边界外(即不允许环绕)。

示例 1:

1
2
3
输入:matrix = [[9,9,4],[6,6,8],[2,1,1]]
输出:4
解释:最长递增路径为 [1, 2, 6, 9]。

示例 2:

1
2
3
输入:matrix = [[3,4,5],[3,2,6],[2,2,1]]
输出:4
解释:最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 200
  • 0 <= matrix[i][j] <= 2^31 - 1

思路

最朴素的方法为依次$dfs$每个点,找到从每个点开始的最长递增路径的最大值,然后求$max$。

记忆化$dfs$:由于朴素$dfs$会对同一路径进行大量重复操作,时间复杂度为指数级别。我们可以用$f[i][j]$记录从(i,j)出发可以得到的最长递增路径。下次$dfs$到这个坐标可以直接拿来用。

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
36
37
38
39
class Solution {
public:
int n,m;
int ans=0;
// f[i][j]:从(i,j)出发可以获得的最长递增路径
int f[210][210];

int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

// 记忆化搜索
int dfs(vector<vector<int>>& matrix,int x,int y){
if(f[x][y]){
return f[x][y];
}

// 最短为1
f[x][y]=1;
for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&matrix[xx][yy]>matrix[x][y]){
f[x][y]=max(f[x][y],dfs(matrix,xx,yy)+1);
}
}
return f[x][y];
}

int longestIncreasingPath(vector<vector<int>>& matrix) {
n=matrix.size();
m=matrix[0].size();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
ans=max(ans,dfs(matrix,i,j));
}
}
return ans;
}
};

时间复杂度:$O(mn)$,$n$为矩阵的行数,$m$为矩阵的列数。在$dfs$中,时间复杂度为$O(V+E)$,$V$为结点数,$E$为边数$O(V)=O(mn)$,$O(E)\approx O(4mn)$,每个点上下左右四条边。

空间复杂度:$O(mn)$

您的支持是我继续创作的最大动力!