leetcode329. 矩阵中的最长递增路径
给定一个整数矩阵,找出最长递增路径的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。
示例 1:
输入: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
输出: 4
解释: 最长递增路径为 [1, 2, 6, 9]。
示例 2:
输入: nums =
[
[3,4,5],
[3,2,6],
[2,2,1]
]
输出: 4
解释: 最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。
方法:深度优先搜索DFS+记忆化
思路:
本题上下左右都可以走,很容易想到深度优先搜索DFS来从一个点开始找到该点的最长递增路径。
然后,我们遍历所有的点,找到所有点为起点的路径中最长的即可。
但是,这种情况会出现大量的重复计算,因为后续点可能包含在前面某个点的最长路径中,这样这个点就已经计算过一次了,造成了重复计算,因此,我们使用一个备忘录数组memo,memo(i,j)就保存以matrix(i,j)为起点的最长递增序列的长度。
我们的主函数进行如下操作:
- 双循环按顺序遍历matrix的所有点,使用res保存答案。
- 遍历到某点时,如果memo(i,j)不等于0,说明之前已经遍历过,
res = max(res,memo[i][j])
- 如果此时memo(i,j)等于0,说明之前没有遍历过该点,调用dfs来找到该点的memo值,再更新res。在调用dfs的过程中,也更新了该点为起点的路径上的其他一些点的memo值,等到遍历到这些点的时候就不需要计算了。
我们的dfs函数进行如下操作:
- 遍历四个方向,使用temp来保存序列长度,temp初始为1,表示只有该点自己。
- 对每个方向,如果这个方向点不越界,且点的值大于(i,j)的值,那么就可以连成递增序列。
- 如果这个方向点的memo值存在,那么直接加上;如果不存在,递归调用dfs求得。
- 最后综合四个方向,找到最大的temp,更新该点的memo,返回temp。
代码:
Python3:
class Solution:
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
m = len(matrix)
if not m:
return 0
n = len(matrix[0])
res = 0
# 初始化记忆化数组,0表示还没有填写过,memo[i][j]表示从matrix[i][j]为起点的
# 最长递增序列的长度
memo = [[0 for _ in range(n)] for _ in range(m)]
# 四个方向的位置
directions = [(-1,0),(1,0),(0,</