Python DFS BFS实现 Leetcode200 岛屿数量 Leetcode695岛屿的最大面积 Leetcode463 岛屿的周长 Leetcode257 二叉树的所有路径

深搜思想(DFS) 实现起来代码更简洁一点,但是不利于理解,深搜一般用到了递归结构,即在函数中不断调用自己(但函数的参数变量肯定会变);

宽搜思想(BFS) 符合人们的正常思维,但需要构建一个队列进行维护,不断取出队列头部元素并判断其周围元素。

拿岛屿问题来讲: 深搜每次扩展一个格子,宽搜每次扩展一层格子

但是根据我的做题经验来看,深搜能解决的问题比宽搜多的多,如二叉树,树形结构的问题(回溯法问题)都可以用深搜DFS解决,并且DFS照比BFS快得多

一、岛屿数量

在这里插入图片描述

from collections import deque
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        # 深搜实现起来代码简洁一点,但是不利于理解,宽搜思想符合人们的正常思维,但是需要构建一个数组进行维护,不断从头部取出元素判断其周围元素
        # 深搜每次扩展一个格子
        def dfs(grid, i, j):
            # 如果此位置超出岛屿边界或者此位置不存在岛屿,则推出深搜
            if not 0<= i < len(grid) or not 0<=j<len(grid[0]) or grid[i][j] == "0":
                return # 退出深搜
            grid[i][j]= '0' # 把搜索过的位置标记,避免重复记录
            dfs(grid, i, j+1) # 右
            dfs(grid, i+1, j) # 下
            dfs(grid, i, j-1) # 左
            dfs(grid, i-1, j) # 上
            
        def bfs(grid, i, j):
            # 构建队列
            neighbors = deque([(i,j)])
            # 如果队列非空
            while neighbors:
                # 找到此时位置
                i,j = neighbors.popleft()
                # 宽搜每次扩展一层格子
                for x,y in [(i, j+1),(i+1, j),(i, j-1),(i-1, j)]: # 按照右上左下的顺序依次遍历
                    if 0<=x<len(grid) and 0<= y< len(grid[0]) and grid[x][y] == "1":
                        neighbors.append((x,y))
                        grid[x][y] = "0"
        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1': # 找到岛屿中其中一个陆地的位置
                    # bfs(grid, i,j)
                    dfs(grid, i,j)
                    count +=1
        return count

二、岛屿的最大面积

在这里插入图片描述
在这里插入图片描述

# 岛屿数量问题看好list里传入的是字符还是int
from collections import deque
class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        # 在函数内部构建dfs bfs 函数
        def dfs(grid, i,j):
            if not 0<=i<len(grid) or not 0<=j<len(grid[0]) or grid[i][j] == 0:
                return 0 # 退出dfs搜索
            # 每次搜索时,都应该将count +=1
            grid[i][j] = 0
            count = 1
            print(id(count))
            for di,dj in [[0,1],[1,0],[0,-1], [-1,0]]:
                next_i ,next_j = i+di, j+dj
                count += dfs(grid, next_i, next_j)

            # 返回的count是最终的结果
            return count # 要把count返回回去,跟res比较哪个大

        def bfs(grid,i,j):
            neighbors = deque([(i,j)])
            count = 0 # count是0还是1呢,应该是0,分析一下:此时的i和j符合一个陆地,
            # 在后面的bfs中,会将这个位置搜索出来,此时只是将这个位置定位一个起点
            while neighbors:
                i,j = neighbors.popleft()
                if not 0<=i<len(grid) or not 0<=j<len(grid[0]) or grid[i][j]==0:
                #if i<0 or i== len(grid) or j<0 or j== len(grid[0]) or grid[i][j] == 0:
                    continue
                count +=1
                for x,y in [(i,j+1),(i+1,j),(i,j-1),(i-1,j)]: 
                    neighbors.append((x,y))
            return count

        res = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1: # 找到陆地位置
                    # 实现dfs或者bfs
                    count = dfs(grid,i,j)
                    # count = bfs(grid,i,j)
                    res = max(res, count)
        return res

三、岛屿的周长

在这里插入图片描述

from collections import deque
class Solution:
    def islandPerimeter(self, grid: List[List[int]]) -> int:
        def bfs(grid,i,j):
            neighbors = deque([(i,j)])
            count = 0
            while neighbors:
                i,j = neighbors.popleft()
                # 避免重复统计
                grid[i][j] = 2
                for x,y in [(i,j+1),(i+1,j),(i,j-1),(i-1,j)]:
                    # 遇到边界或者水域,则周长加一
                    if x<0 or x>=len(grid) or y<0 or y>=len(grid[0]) or grid[x][y] ==0:
                        count +=1
                    # 相邻区域为陆地,则将其标记为2,加入队列
                    elif grid[x][y] == 1:
                        grid[x][y] = 2 
                        neighbors.append((x,y))
                    # 相邻区域为已标记陆地,则不做处理
            return count

        def dfs(grid, i,j):   
            perimeter = 0
            grid[i][j] = 2
            for di,dj in [[0,1],[1,0],[0,-1], [-1,0]]:
                next_i ,next_j = i+di, j+dj
                if next_i<0 or next_i>=len(grid) or next_j<0 or next_j>=len(grid[0]) or grid[next_i][next_j] ==0:
                    perimeter+=1
                elif grid[next_i][next_j] == 2:
                    continue
                elif grid[next_i][next_j] == 1:
                    perimeter+=dfs(grid,next_i,next_j)
            return perimeter
            
        res = 0  
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1: # 找到陆地位置
                    # 实现dfs或者bfs
                    res += dfs(grid,i,j)
                    # count = bfs(grid,i,j)
        # return count
        return res
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值