题目
给一个矩阵,找到它最长上升路径的长度。对于每一个点,它可以上下左右移动,但是不能斜对角移动。
Example:
Input: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].
解题思路
最直观的方法是,以矩阵中的每一个点作为起点,对每一个点用dfs搜索,然后求取最大值。直接上代码
class Solution:
def __init__(self):
self.ans = 0
def dfs(self, Matrix, i, j, length):
self.ans = max(self.ans, length)
# 开始四个方向 dfs
if i - 1 >= 0 and Matrix[i][j] < Matrix[i-1][j]:
self.dfs(Matrix, i-1,j,length + 1)
if i + 1 < len(Matrix) and Matrix[i][j] < Matrix[i+1][j]:
self.dfs(Matrix, i+1,j,length + 1)
if j - 1 >= 0 and Matrix[i][j] < Matrix[i][j-1]:
self.dfs(Matrix, i,j-1,length + 1)
if j + 1 < len(Matrix[0]) and Matrix[i][j] < Matrix[i][j+1]:
self.dfs(Matrix, i,j+1,length + 1)
def longestIncreasingPath(self, Matrix):
if len(Matrix)==0:
return 0
result = 1
for i in range(len(Matrix)):
for j in range(len(Matrix[0])):
# 以每一个点为起点,起点长度为1,进行dfs.
self.dfs(Matrix, i, j, 1)
return self.ans
if __name__=='__main__':
S = Solution()
List = [[9,9,4],
[6,6,8],
[2,1,1]]
print(S.longestIncreasingPath(List))
上面的方法,做了很多重复dfs的工作。我们对上面的方法可以进行一个剪枝优化,用记忆化dfs搜索,如果dfs到某一个点,发现该点已经被访问过了,那么就可以直接返回该点为起点的最长路径值,停止往下搜索。比如dfs到点6,我们只需要保存当前点6离终点还有多远,然后保存该值,并且标记为访问过了。如果再次dfs到点6,我们发现如果访问过了,就不用再进行dfs了,只需要返回该点保存的离终点的距离值+1(点6本身)就好了。
# 记忆化优先搜索
class Solution:
def dfs(self, Matrix, Men, i, j):
# 初始化为0,如果不为零,说明已经搜索过了
if Men[i][j] != 0:
return Men[i][j]
# 最少为1,包含自己
Men[i][j] += 1
# 四个方向进行dfs
if i - 1 >= 0 and Matrix[i][j] < Matrix[i-1][j]:
Men[i][j] = max(Men[i][j], self.dfs(Matrix, Men,i-1,j) + 1)
if i + 1 < len(Matrix) and Matrix[i][j] < Matrix[i+1][j]:
Men[i][j] = max(Men[i][j], self.dfs(Matrix, Men, i+1, j) + 1)
if j - 1 >= 0 and Matrix[i][j] < Matrix[i][j-1]:
Men[i][j] = max(Men[i][j], self.dfs(Matrix, Men, i, j-1) + 1)
if j + 1 < len(Matrix[0]) and Matrix[i][j] < Matrix[i][j+1]:
Men[i][j] = max(Men[i][j], self.dfs(Matrix, Men, i, j+1) + 1)
return Men[i][j]
def longestIncreasingPath(self, Matrix):
if len(Matrix)==0:
return 0
ans = 1
###
# 初始化访问标记值为0,如果访问标记值为0,则代表未被访问过,继续dfs,
# 如果已被访问过,即里面的值大于0(实际上该值代表以该点为起点,最长上升路径长度),
# 则不必要再对该点进行dfs了.
###
self.Men = [[0 for i in range(len(Matrix[0]))] for j in range(len(Matrix))]
for i in range(len(Matrix)):
for j in range(len(Matrix[0])):
ans = max(ans, self.dfs(Matrix, self.Men, i, j))
return ans
if __name__=='__main__':
S = Solution()
List = [[9,9,4],
[6,6,8],
[2,1,1]]
print(S.longestIncreasingPath(List))