返回

从不同角度理解记忆化DFS,剖析LeetCode329: 矩阵中的最长递增路径

后端

理解问题

给定一个包含正整数的矩阵,要求找到矩阵中从任意位置出发,经过相邻元素形成的最长递增路径。相邻元素是指上下左右四个方向的元素。

算法原理

记忆化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),大大提高了算法的效率。