329 矩阵中的最长递增路径(记忆化dfs搜索)

1. 问题描述:

给定一个 m x n 整数矩阵 matrix ,找出其中最长递增路径的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。

示例 1:

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

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

示例 3:

输入:matrix = [[1]]
输出:1

提示:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-path-in-a-matrix

2. 思路分析:

分析题目可以知道我们可以枚举矩阵中的所有位置并且以当前位置作为起点开始dfs搜索,这样可以求解以当前位置(i, j)为起点出发的最长递增路径,因为每一个格子都有上下左右四种走法,而且矩阵最大的行数和列数最大为200所以最多可能有4 ^ 200种尝试的可能所以使用一般的dfs搜索肯定是会超时的我们需要使用记忆化的搜索减少重复性的递归,因为当你走到一个格子的时候之前这个位置已经被求解过了那么就没有必要往下再求解了(之前已经对这个格子搜素完全部的路径并且当前位置的值就是以当前起点的最长递增路径),因为从当前这个位置往下走又是和之前一样重复性的递归,所以我们可以使用一个二维数组或者列表记录一下已经求解过的位置,这样可以避免重复子问题的求解,减小时间复杂度。题目中说了路径是完全递增的,所以在dfs搜索的过程中是不存在环的,所以最终路径的起点与终点是不存在环的所以不用标记数组或者列表。

3. 代码如下:

from typing import List


class Solution:
    pos = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    r, c = 0, 0
    # f为记忆化列表
    def dp(self, x: int, y: int, f: List[List[int]], w: List[List[int]]):
        # 当前位置为起点对应的最长递增路径
        v = f[x][y]
        if v != -1: return v
        v = 1
        for i in range(4):
            x1, y1 = x + self.pos[i][0], y + self.pos[i][1]
            # 尝试四个可以走的方向
            if 0 <= x1 < self.r and 0 <= y1 < self.c and w[x1][y1] > w[x][y]:
                v = max(v, self.dp(x1, y1, f, w) + 1)
        # 更新记忆化列表的值
        f[x][y] = v
        return v

    def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
        r, c = len(matrix), len(matrix[0])
        if r == 0 or c == 0: return 0
        self.r, self.c = r, c
        res = 0
        f = [[-1] * c for i in range(r)]
        for i in range(r):
            for j in range(c):
                # 尝试矩阵中的每一个起点开始的最长递增路径
                res = max(res, self.dp(i, j, f, matrix))
        return res

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值