LeetCode 329.矩阵中的最长递增路径
题目:
给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。
示例 1:
输入:matrix = [[9,9,4],[6,6,8],[2,1,1]]
输出:4
解释:最长递增路径为 [1, 2, 6, 9]。
示例 2:
输入:matrix = [[3,4,5],[3,2,6],[2,2,1]]
输出:4
解释:最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。
示例 3:
输入:matrix = [[1]]
输出:1
记忆化深搜:
以每个单元格为起点开始搜索,找到上下左右能到的最大长度就是以当前单元格为起点的最大长度,然后再在所有单元格找最大值即可
class Solution {
public:
int longestIncreasingPath(vector <vector<int>> &matrix) {
int Map[210][210] = {0};//每个点的最短路径
int m = matrix.size();
int n = matrix[0].size();
int Max = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
Max = max(dfs(matrix, m, n, i, j, Map), Max);
}
}
return Max;
}
int dfs(vector <vector<int>> &matrix, int m, int n, int x, int y, int Map[210][210]) {
if (Map[x][y]) return Map[x][y];
int val = 0;
int mark[][2] = {{0, 1},
{0, -1},
{1, 0},
{-1, 0}};
for (int i = 0; i < 4; i++) {
int tx = x + mark[i][0];
int ty = y + mark[i][1];
if (tx >= 0 && tx < m && ty >= 0 && ty < n && matrix[tx][ty] < matrix[x][y]) {
val = max(val, dfs(matrix, m, n, tx, ty, Map));
}
}
Map[x][y] = val + 1;
return Map[x][y];
}
};
动态规划:
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为 以
m
a
t
r
i
x
[
i
]
[
j
]
matrix[i][j]
matrix[i][j]为终点的最大递增序列
d
p
[
i
]
[
j
]
=
m
a
x
(
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
+
1
]
[
j
]
)
,
m
a
x
(
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
]
[
j
+
1
]
)
)
+
1
(
m
a
t
r
i
x
[
i
+
−
1
]
[
j
+
−
1
]
<
m
a
t
r
i
x
[
i
]
[
j
]
)
dp[i][j]=max(max(dp[i-1][j],dp[i+1][j]),max(dp[i][j-1],dp[i][j+1]))+1\\ (matrix[i+-1][j+-1]<matrix[i][j])
dp[i][j]=max(max(dp[i−1][j],dp[i+1][j]),max(dp[i][j−1],dp[i][j+1]))+1(matrix[i+−1][j+−1]<matrix[i][j])
所以从
m
a
t
r
i
x
matrix
matrix排序之后从小到大
d
p
dp
dp
然后再 m a t r i x [ i ] [ j ] matrix[i][j] matrix[i][j]的上下左右找到值小于 m a t r i x [ i ] [ j ] matrix[i][j] matrix[i][j]的 d p [ i + − 1 ] [ j + − 1 ] dp[i+-1][j+-1] dp[i+−1][j+−1]的最大值加一就是当前 d p [ i ] [ j ] dp[i][j] dp[i][j]的值
因为是从小到大 d p dp dp的,所以上下左右小于 m a t r i x [ i ] [ j ] matrix[i][j] matrix[i][j]的单元格一定被算过
class Solution {
public:
struct A {
int x;
int y;
int val;
};
static bool is_A(struct A a, struct A b) {
return a.val < b.val;
}
int longestIncreasingPath(vector <vector<int>> &matrix) {
int m = matrix.size();
int n = matrix[0].size();
int len = 0;
struct A arr[40010];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
arr[len].x = i;
arr[len].y = j;
arr[len].val = matrix[i][j];
len++;
}
}
sort(arr, arr + len, is_A);
int dp[210][210] = {0};
int Max = 0;
int mark[][2] = {{0, 1},
{0, -1},
{-1, 0},
{1, 0}};
for (int i = 0; i < len; i++) {
int M = 0;
for (int j = 0; j < 4; j++) {
int tx = arr[i].x + mark[j][0];
int ty = arr[i].y + mark[j][1];
if (tx >= 0 && ty >= 0 && tx < m && ty < n && matrix[tx][ty] < matrix[arr[i].x][arr[i].y]) {
M = max(M, dp[tx][ty]);
}
}
dp[arr[i].x][arr[i].y] = 1 + M;
Max = max(Max, dp[arr[i].x][arr[i].y]);
}
return Max;
}
};