代码随想录图论

1. 所有可能的路径

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
        
        def dfs(graph, result, path, root):     #result 返回结果, path记录路径, root记录遍历到了第几个节点
            if root == len(graph) - 1:          #如果遍历到最后一个节点,记录结果并返回
                result.append(path.copy())      
                return
            for i in graph[root]:               #遍历每个节点下一个能到的下一个节点
                path.append(i)                  #path直接添加
                dfs(graph, result, path, i)     #dfs递归, 输入的root直接变成i,也就是当前遍历的下一个
                path.pop()                      #回溯
        result = []
        path = [0]                              #初始化的时候path里已经有最初始的节点位置
        root = 0                                #起始节点为0
        dfs(graph, result, path, root)
        return result

实际上就是回溯算法,区别在于:之前做的回溯的题目一般是列表里面一个一个元素遍历,所以在递归的时候有一个start_index变量,控制选与不选当前元素。

而dfs搜索找下一个节点的时候,不用一个个遍历graph中的节点,而是只需要遍历当前节点能到达的节点,因为如果当前节点都到不了的节点,就没有必要往后遍历了。

因此递归的dfs的输入就变成了当前遍历的节点i

2. 岛屿数量

广搜 bfs版本

class Solution:
    def __init__(self):
        self.dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]
        self.count = 0

    def bfs(self, grid, visited, x, y):                                                     #广搜函数定义
        from collections import deque   
        queue = deque()                                                                     #初始化队列
        queue.append((x, y))                                                                #加入起始节点
        visited[x][y] = True                                                                #标记起始节点为已访问
        while queue:                                                                        #队列不为空进入循环
            curx, cury = queue.popleft()                                                    #取头节点
            for dx, dy in self.dir:                                                         #遍历四个方向
                nextx ,nexty = curx + dx, cury + dy                                     
                
                if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]):   #越界就跳过
                    continue
                if grid[nextx][nexty] == "0":                                               #如果本题中是海水也跳过
                    continue
                if not visited[nextx][nexty]:                                               #把所有陆地标记为已访问
                    queue.append((nextx, nexty))
                    visited[nextx][nexty] = True
    
    def numIslands(self, grid: List[List[str]]) -> int:
        visited = [[False] * len(grid[0]) for _ in range(len(grid))]                        #初始化访问数组
        for i in range(len(grid)):
            for j in range(len(grid[0])):                                                   #遍历grid
                if visited[i][j] == False and grid[i][j] == "1":                            #如果节点没被访问过以及是陆地
                    self.count += 1                                                         #计数+1
                    self.bfs(grid, visited, i, j)                                           #深搜一下把当前节点连通的所有陆地都标记为已访问
        return self.count
        

3. 岛屿最大面积

class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:

        def bfs(grid, visited, x, y):
            from collections import deque                           
            q = deque()                                                 #初始化队列
            q.append((x, y))                                            #加入起点
            visited[x][y] = True                                        #标记已遍历起点
            cnt = 1                                                     #记录岛屿大小
            direction = [(-1, 0), (0, -1), (1, 0), (0, 1)]              #四个方向
            while(q):                                                   #循环遍历队列中的节点
                curx, cury = q.popleft()                                #取出第一个节点
                for dx, dy in direction:                                #遍历四个方向
                    nextx, nexty = curx + dx, cury + dy
                    
                    if nextx < 0 or nextx >= len(grid):                 #越界直接跳过
                        continue
                    if nexty < 0 or nexty >= len(grid[0]):
                        continue
                    if grid[nextx][nexty] == 0:                         #不是岛屿也直接跳过
                        continue
                    if not visited[nextx][nexty]:                       #是岛屿的部分
                        q.append((nextx, nexty))                        #加入节点
                        visited[nextx][nexty] = True                    #标记为已访问
                        cnt += 1                                        #面积加1
            return cnt                                                  #返回当前起点的岛屿大小
        result = 0
        visited = [[False] * len(grid[0]) for _ in range(len(grid))]
        for i in range(len(grid)):                                      #遍历网格
            for j in range(len(grid[0])):                                 
                if not visited[i][j] and grid[i][j] == 1:               #让每个是岛屿的节点并且没被访问过的点作为起点去BFS
                    cur = bfs(grid, visited, i, j)                      #记录当前节点为起点的岛屿大小
                    result = max(cur, result)                           #记录最大的岛屿大小
        return result

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值