代码随想录算法训练营Day 61| 图论 part01 | 797.所有可能的路径、200.岛屿数量(深搜)

代码随想录算法训练营Day 61| 图论 part01 | 797.所有可能的路径、200.岛屿数量(深搜)(广搜)



797.所有可能的路径

题目链接

一、DFS

class Solution(object):
    def allPathsSourceTarget(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: List[List[int]]
        """
        res = []
        path = []
        def dfs(x):
            if x==len(graph)-1:
                res.append(path[:])
                return 
            for i in graph[x]:
                path.append(i)
                dfs(i)
                path.pop()
        path.append(0)
        dfs(0)
        return res
        

二、两种写法

邻接矩阵写法


def dfs(graph, x, n, path, result):
    if x == n:
        result.append(path.copy())
        return
    for i in range(1, n + 1):
        if graph[x][i] == 1:
            path.append(i)
            dfs(graph, i, n, path, result)
            path.pop()  # 回溯,移除路径中的最后一个节点

def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    index = 0
    
    n = int(data[index])
    index += 1
    m = int(data[index])
    index += 1
    
    graph = [[0] * (n + 1) for _ in range(n + 1)]
    
    for _ in range(m):
        s = int(data[index])
        index += 1
        t = int(data[index])
        index += 1
        graph[s][t] = 1
    
    result = []
    path = [1]
    dfs(graph, 1, n, path, result)
    
    if len(result) == 0:
        print(-1)
    else:
        for pa in result:
            print(' '.join(map(str, pa)))

if __name__ == '__main__':
    main()

邻接表写法


def dfs(graph, x, n, path, result):
    if x == n:
        result.append(path.copy())
        return
    for i in graph[x]:
        path.append(i)
        dfs(graph, i, n, path, result)
        path.pop()  # 回溯,移除路径中的最后一个节点

def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    index = 0
    
    n = int(data[index])
    index += 1
    m = int(data[index])
    index += 1
    
    graph = [[] for _ in range(n + 1)]  # 邻接表实现
    
    for _ in range(m):
        s = int(data[index])
        index += 1
        t = int(data[index])
        index += 1
        graph[s].append(t)  # 填充邻接表
    
    result = []
    path = [1]  # 路径开始节点设为1
    dfs(graph, 1, n, path, result)  # 从节点1开始DFS
    
    if not result:
        print(-1)
    else:
        for pa in result:
            print(' '.join(map(str, pa)))

if __name__ == '__main__':
    main()

广度优先搜索理论基础

在这里插入图片描述
本题思路:遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。

再遇到标记过的陆地节点和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量。

那么如果把节点陆地所能遍历到的陆地都标记上呢,就可以使用 DFS,BFS或者并查集。

一、示例

from collections import deque

dir = [(0, 1), (1, 0), (-1, 0), (0, -1)] # 创建方向元素

def bfs(grid, visited, x, y):
  
  queue = deque() # 初始化队列
  queue.append((x, y)) # 放入第一个元素/起点
  visited[x][y] = True # 标记为访问过的节点
  
  while queue: # 遍历队列里的元素
  
    curx, cury = queue.popleft() # 取出第一个元素
    
    for dx, dy in dir: # 遍历四个方向
    
      nextx, nexty = curx + dx, cury + dy
      
      if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]): # 越界了,直接跳过
        continue
        
      if not visited[nextx][nexty]: # 如果节点没被访问过  
        queue.append((nextx, nexty)) # 加入队列
        visited[nextx][nexty] = True # 标记为访问过的节点

200.岛屿数量(深搜)

题目链接

一、法一

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        m,n=len(grid),len(grid[0]) # row,col
        # print(m,n)
        visited = [[False]*n for _ in range(m)]
        dirs = [(-1,0),(0,1),(1,0),(0,-1)]
        result = 0
        def dfs(x,y):
            for d in dirs:
                nextx = x+d[0]
                nexty = y+d[1]
                if nextx<0 or nextx>=m or nexty<0 or nexty>=n:
                    continue
                if visited[nextx][nexty] ==False and grid[nextx][nexty]=='1':
                    visited[nextx][nexty]=True
                    dfs(nextx,nexty)

        for i in range(m):
            for j in range(n):
              if not visited[i][j] and grid[i][j]=='1':
                visited[i][j]=True
                dfs(i,j)
                result +=1
        return result

二、法二

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        m,n=len(grid),len(grid[0]) # row,col
        # print(m,n)
        visited = [[False]*n for _ in range(m)]
        dirs = [(-1,0),(0,1),(1,0),(0,-1)]
        result = 0
        # 法2
        def dfs(x,y):
            if visited[x][y] or grid[x][y]=='0':
                return 
            visited[x][y]=True
            for d in dirs:
                nextx = x+d[0]
                nexty = y+d[1]
                if nextx<0 or nextx>=m or nexty<0 or nexty>=n:
                    continue
                dfs(nextx,nexty)
        for i in range(m):
            for j in range(n):
                if visited[i][j]==False and grid[i][j]=='1':
                    dfs(i,j)
                    result +=1
        return result

三、本题总结

版本一的写法是 :下一个节点是否能合法已经判断完了,传进dfs函数的就是合法节点。

版本二的写法是:不管节点是否合法,上来就dfs,然后在终止条件的地方进行判断,不合法再return。

200.岛屿数量(广搜)

题目链接

一、法一

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        m,n=len(grid),len(grid[0]) # row,col
        # print(m,n)
        visited = [[False]*n for _ in range(m)]
        dirs = [(-1,0),(0,1),(1,0),(0,-1)]
        result = 0
        def bfs(i,j):
            q = collections.deque()
            q.append((i,j))
            visited[i][j]=True
            while q:
                x,y = q.popleft()
                for d in dirs:
                    nextx = x+d[0]
                    nexty = y+d[1]
                    if nextx<0 or nextx>=m or nexty<0 or nexty>=n:
                        continue
                    if visited[nextx][nexty] or grid[nextx][nexty]=='0':
                        continue
                    q.append((nextx,nexty))
                    visited[nextx][nexty]=True
        for i in range(m):
            for j in range(n):
               if not visited[i][j] and grid[i][j]=='1':
                    result +=1
                    bfs(i,j)
        return result 
                

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值