深度优先搜索DFS | 拓扑排序:力扣329. 矩阵中的最长递增路径

1、题目描述:

在这里插入图片描述

2、题解:

方法1:带记忆化的深度优先搜索 DFS
思路:

用memo存已经计算过的单元格
遍历数组中每个单元格,如果未被访问就DFS,然后更新res.
在DFS中,如果该点已经访问过,就返回访问的值,否则就在四个方向上如果满足比该点的值大 就继续DFS,最后更新memo。

Python代码如下:

class Solution:
    def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
        #DFS
        if not matrix or not matrix[0]:
            return 0
        row,col = len(matrix),len(matrix[0])
        directions = [(-1,0),(1,0),(0,1),(0,-1)]#四个方向
        memo = [[0] * col for _ in range(row)]
        res = 0
        
        def dfs(row,col):
            if memo[row][col]:return memo[row][col]
            else:
                memo[row][col] = 1
                for direction in directions:
                    x = row + direction[0]
                    y = col + direction[1]
                    if   0 <= x < len(matrix) and 0 <= y < len(matrix[0]) and \
                        matrix[row][col] < matrix[x][y]:
                        memo[row][col] = max(memo[row][col],dfs(x,y) + 1)               
                return memo[row][col]
                
        for i in range(row):
            for j in range(col):
                if memo[i][j] == 0:dfs(i,j)
                res = max(res,memo[i][j])
        return res

方法2:拓扑排序
思路:

仍然使用方法一的思想,将矩阵看成一个有向图,计算每个单元格对应的出度,即有多少条边从该单元格出发。
对于作为边界条件的单元格,该单元格的值比所有的相邻单元格的值都要大,因此作为边界条件的单元格的出度都是0。
基于出度的概念,可以使用拓扑排序求解。从所有出度为0的单元格开始广度优先搜索,每一轮搜索都会遍历当前层的所有单元格,更新其余单元格的出度,并将出度变为0
的单元格加入下一层搜索。当搜索结束时,搜索的总层数即为矩阵中的最长递增路径的长度。

Python代码如下:

class Solution:
    def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
        #拓扑排序
        directions = [(-1,0),(1,0),(0,1),(0,-1)]#四个方向
        if not matrix or not matrix[0]:return 0
        row,col = len(matrix),len(matrix[0])
        outdegrees = [[0] * col for _ in range(row)]
        queue = collections.deque()
        for i in range(row):
            for j in range(col):
                for x,y in directions:
                    newrow,newcol = i +x,j + y
                    if 0 <= newrow < row and 0 <= newcol < col and matrix[i][j] >  matrix[newrow][newcol]:
                        outdegrees[i][j] += 1
                if outdegrees[i][j] == 0:
                    queue.append((i,j))
        res = 0
        while queue:
            res += 1
            size = len(queue)
            for _ in range(size):
                row,col = queue.popleft()
                for x,y in directions:
                    newrow ,newcol = row + x,col + y
                    if 0 <= newrow < len(matrix) and 0 <= newcol < len(matrix[0]) and \
                            matrix[row][col] < matrix[newrow][newcol]:
                        outdegrees[newrow][newcol] -= 1
                        if outdegrees[newrow][newcol] == 0:
                            queue.append((newrow,newcol))
        return res

3、复杂度分析:

方法1:
时间复杂度:O(MN),M、N别为矩阵的行数和列数
空间复杂度:O(MN)
方法2:
时间复杂度:O(MN),M、N别为矩阵的行数和列数
空间复杂度:O(M
N)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值