DFS或BFS:力扣面试题 16.19. 水域大小

1、题目描述:

在这里插入图片描述

2、题解:

方法1:BFS

BFS 的几个主要步骤:
1、肯定会用到 deque 的结构用来模拟队列,BFS精髓也在这里。
2、队列里肯定是有一个初始点
3、然后每次处理从队列中出队一个元素
4、对元素进行扩张(具体如何扩张需要根据题目要求,一般是上下左右四个方向,本题是算上斜向共8个方向)
5、对于扩张后满足某条件的点再进行处理,根据需要进入队列,进入队列的点就是扩到下一层的点(不同题目需要
处理的方法不同,大家灵活运用)
6、然后接着循环处理 deque 中的元素,直到 deque 为空,则代表所有点都已经完成扩张
7、最后根据题目要求输出结果(当然这已经不属于 BFS 模板的范围了)

代码如下:

class Solution:
    def pondSizes(self, land: List[List[int]]) -> List[int]:
        # BFS
        res = []
        for row in range(len(land)):
            for col in range(len(land[0])):
                if land[row][col] == 0:
                    temp = collections.deque()
                    temp_count = 1
                    land[row][col] = -1 #将访问的点进行标记
                    temp.append([row,col])
                    while len(temp) > 0:
                        x,y = temp.popleft()
                        for new_x,new_y in [[x + 1,y],[x - 1,y],[x + 1,y + 1],[x - 1, y + 1],\
                                            [x + 1, y - 1],[x - 1,y - 1],[x, y + 1],[x, y - 1]]:
                            if 0 <= new_x < len(land) and 0 <= new_y < len(land[0]) and land[new_x][new_y] == 0:
                                temp_count += 1
                                land[new_x][new_y] = -1
                                temp.append([new_x,new_y])
                    res.append(temp_count)
        return sorted(res)

或者:

class Solution:
    def pondSizes(self, land: List[List[int]]) -> List[int]:
        # BFS,剪枝
        res = []
        direction = [(1,0),(-1,0),(1,1),(0,1),(-1,1),(1,-1),(0,-1),(-1,-1)] #8个方向
        visited = [[0 for _ in range(len(land[0]))] for _ in range(len(land))]
        for row in range(len(land)):
            for col in range(len(land[0])):
                if land[row][col] == 0 and visited[row][col] == 0: #为水域,并且未被访问
                    temp = collections.deque()
                    temp_count = 1
                    visited[row][col] = 1 #将访问的点进行标记
                    temp.append([row,col])
                    while len(temp) > 0:
                        x,y = temp.popleft()
                        for i ,j  in direction:
                            new_x,new_y = x + i,y + j
                            if 0 <= new_x < len(land) and 0 <= new_y < len(land[0]) and land[new_x][new_y] == 0 and visited[new_x][new_y] == 0:
                                temp_count += 1
                                visited[new_x][new_y] = 1
                                temp.append([new_x,new_y])
                    res.append(temp_count)
        return sorted(res)

方法2:DFS
DFS+剪枝
用seen 保存已经遍历的池塘

class Solution:
    def pondSizes(self, land: List[List[int]]) -> List[int]:
        # DFS
        n, m = len(land), len(land[0])
        self.direction = [(0, 1), (1, 0), (1, 1), (-1, -1), (0, -1), (-1, 0), (-1, 1), (1, -1)]  # 8个方向
        self.seen = [[0] * m for _ in range(n)]
        res = []
        for i in range(n):
            for j in range(m):
                if self.seen[i][j] == 1 or land[i][j] != 0:
                    continue
                else:  # 仅当遇见没遍历过的池塘时开始dfs
                    self.seen[i][j] = 1
                    res.append(self.dfs(land, i, j))
        return sorted(res)

    def dfs(self, land, x, y):
        n, m = len(land), len(land[0])
        res = 1  # 因为只有当为池塘时才会进行搜索
        for item in self.direction:
            i, j = item
            new_x, new_y = x + i, y + j
            if new_x >= 0 and new_x < n and new_y >= 0 and new_y < m and self.seen[new_x][new_y] == 0:
                self.seen[new_x][new_y] = 1
                if land[new_x][new_y] == 0:
                    res += self.dfs(land, new_x, new_y)
        return res

3、复杂度分析:

方法1:
时间复杂度:O()
空间复杂度:O()
方法2:
时间复杂度:O()
空间复杂度:O()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值