返回
从不同角度理解记忆化DFS,剖析LeetCode329: 矩阵中的最长递增路径
后端
2023-11-28 02:23:57
理解问题
给定一个包含正整数的矩阵,要求找到矩阵中从任意位置出发,经过相邻元素形成的最长递增路径。相邻元素是指上下左右四个方向的元素。
算法原理
记忆化DFS是一种常见的动态规划算法。在DFS的过程中,将访问过的节点和其对应的最长递增路径长度存储在字典中,如果再次访问到相同的节点,则直接返回存储的路径长度,避免重复计算。
代码实现
def longestIncreasingPath(matrix):
"""
:type matrix: List[List[int]]
:rtype: int
"""
# 初始化结果矩阵和备忘录
result = [[0] * len(matrix[0]) for _ in range(len(matrix))]
memo = {}
# 定义深度优先搜索函数
def dfs(i, j):
# 如果当前节点已经计算过,直接返回
if (i, j) in memo:
return memo[(i, j)]
# 初始化当前节点的最长路径长度为1
max_path = 1
# 检查上下左右四个方向
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
# 计算相邻节点的坐标
x = i + dx
y = j + dy
# 如果相邻节点在矩阵内且值大于当前节点
if 0 <= x < len(matrix) and 0 <= y < len(matrix[0]) and matrix[x][y] > matrix[i][j]:
# 计算相邻节点的最长路径长度
path = dfs(x, y)
# 更新当前节点的最长路径长度
max_path = max(max_path, path + 1)
# 将当前节点的最长路径长度存储在备忘录中
memo[(i, j)] = max_path
# 返回当前节点的最长路径长度
return max_path
# 遍历矩阵,计算每个节点的最长路径长度
for i in range(len(matrix)):
for j in range(len(matrix[0])):
result[i][j] = dfs(i, j)
# 返回最大路径长度
return max(max(row) for row in result)
时间复杂度分析
使用记忆化DFS可以将时间复杂度从O(2^n)优化到O(mn),其中n是矩阵中元素的个数,m是矩阵的行数,n是矩阵的列数。
结语
记忆化DFS是一种非常有用的算法,可以有效地减少重复计算,提高算法的效率。在LeetCode第329题中,记忆化DFS可以将时间复杂度从O(2^n)优化到O(mn),大大提高了算法的效率。