深度优先搜索

深度优先搜索(DFS)类似于树的先序遍历,虽然是针对图的,但是只要在二叉树、图上都可以使用深度优先搜索的思维。

深度优先搜索的过程:

  1. 访问第一个节点,将该节点的状态设置为已访问(因为图可能有环,最后会再次搜索到该节点)
  2. 找到第一个节点的第一个未被访问的邻接节点(这种寻找方式有很多种,根据实际存储结构的不同有不同的处理方式),以该节点为新顶点,重复向下查找新的未被访问的邻接节点,直到当前访问的节点没有邻接节点
  3. 查找上一个未被访问过的且仍有未被访问的邻接点的顶点,并访问它的未被访问的其他节点
  4. 重复2、3,直到所有点都被访问

伪代码:

visited=[]
#x是当前访问的节点,visited是用来存储已访问的节点
def DFS(x):
    print(x.val)
    visited.append(x)
    #在这个位置访问x的所有邻接节点
    #如果该节点也没有被访问,就以他为顶点继续找邻接节点
    for i in (x的所有邻接节点):
        if i not in visited:
            DFS(i)
    

应用:

1.LeetCode 547.省份数量

解法:该题使用visited标记节点是否被访问过。1.若该节点没有被访问过,则对该节点使用深度优先搜索,并使省份数量加一 2.在深度优先搜索中,每访问一个节点,就把它加入到visited中去 3.这样最后深度优先搜索的次数就是省份的数量

注意:该题dfs中的for循环就对饮伪代码中的for循环找所有邻接点

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        def dfs(i: int):
            for j in range(provinces):
                if isConnected[i][j] == 1 and j not in visited:
                    visited.add(j)
                    dfs(j)
        
        provinces = len(isConnected)
        visited = set()
        circles = 0

        for i in range(provinces):
            if i not in visited:
                dfs(i)
                circles += 1
        
        return circles

2.LeetCode 1091. 二进制矩阵中的最短路径

解法:本质还是使用深度优先搜索,看哪一条深度优先搜索的路径先达到终点。需要注意的,在该解法中,使用队列(实际上用列表实现)queue来存储队列中的节点和到该节点需要使用的步数(step)。

注意:while queue下的for循环就对应伪代码中的查找邻接节点。所以不同的存储方式有不同的处理方法

class Solution:
    def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
        n=len(grid)
        if grid[0][0]==1 or grid[n-1][n-1]==1:
            return -1
        if n<=2:
            return n
        queue=[(0,0,1)]
        grid[0][0]=1
        t=[]
        while queue:
            i,j,step=queue.pop(0)
            for x,y in [(-1,-1), (1,0), (0,1), (-1,0), (0,-1), (1,1), (1,-1), (-1,1)]:
                if i+x==n-1 and j+y==n-1:
                    return step+1
                if n>i+x>=0 and n>j+y>=0 and grid[i+x][j+y]==0:
                    queue.append((i+x,j+y,step+1))
                    grid[i+x][j+y]=1
        return -1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值