题目
题目链接
给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 在矩阵中找到一条最长路径
,使这条路径上的元素是递增
的,并输出这条最长路径的长度
这个路径必须满足以下条件:
- 对每个单元格,只能往上,下,左,右四个方向移动
- 不能走重复的单元格,即每个格子最多只能走一次
例:对矩阵
[[1,2,3],
[4,5,6],
[7,8,9]],有最长递增路径1->2->3->6->9,输出长度为5
路径可以不唯一
思路
记忆化搜索(dfs+dp)
如果从矩阵每个元素出发都进行dfs,会有很多重复的子问题
为避免重复求解子问题,设置一个dp矩阵
,记录已搜索到的从当前元素出发的最长路径
;dfs时,再经过这个元素,就可以直接使用之前搜索到的结果
遍历每个元素matrix[i][j]
,进行递归:
- 如果从当前元素出发的最长路径
dp[i][j]
已搜索过,直接返回 - 如果未搜索过,检查
上下左右
四个方向是否满足继续前进的条件,满足则继续递归 - 取向上下左右前进得到的路径长度的最大值,作为
dp[i][j]
的值,并返回
取所有返回值的最大值即为最长路径
代码
class Solution:
def solve(self, matrix):
dp = [[0] * len(matrix[0]) for _ in range(len(matrix))]
maxLen = 0
def rr(i, j):
# 若从当前位置出发的路径已经搜索过,直接返回
# 否则从当前位置出发搜索再返回
if dp[i][j] == 0:
up = rr(i - 1, j) if i - 1 >= 0 and matrix[i][j] < matrix[i - 1][j] else 0
down = rr(i + 1, j) if i + 1 <= len(matrix) - 1 and matrix[i][j] < matrix[i + 1][j] else 0
left = rr(i, j - 1) if j - 1 >= 0 and matrix[i][j] < matrix[i][j - 1] else 0
right = rr(i, j + 1) if j + 1 <= len(matrix[0]) - 1 and matrix[i][j] < matrix[i][j + 1] else 0
dp[i][j] = max(up, down, left, right) + 1
return dp[i][j]
for i in range(len(matrix)):
for j in range(len(matrix[0])):
maxLen = max(rr(i, j), maxLen)
return maxLen