面试题 16.19 水域大小(dfs)

该博客介绍了如何通过深度优先搜索(DFS)算法解决一个二维矩阵中计算池塘(相连的0值区域)大小的问题。首先,从每个0值(水域)开始,使用DFS遍历并标记所有相连的水域,同时记录每片水域的大小。最后,返回所有池塘大小的有序列表。代码中定义了一个Solution类,包含一个dfs方法进行搜索和一个pondSizes方法来初始化和执行搜索过程。
摘要由CSDN通过智能技术生成

1. 问题描述:

你有一个用于表示一片土地的整数矩阵land,该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。

示例:

输入:
[
  [0,2,1,0],
  [0,1,0,1],
  [1,1,0,1],
  [0,1,0,1]
]
输出: [1,2,4]

提示:

  • 0 < len(land) <= 1000
  • 0 < len(land[i]) <= 1000

2. 思路分析:

① 从题目中可以知道我们需要找出矩阵中的每一片联通的水域的个数(注意矩阵中值为0的地方为水域),所以这是一道典型的关于连通性的问题,对于这种连通性的问题经典的做法是dfs搜索,使用dfs搜索从起点出发能够到达的所有水域,一次dfs结束表示的是从一开始的那个起点能够到达的地方都搜索过了,所以我们可以遍历二维矩阵,找出值为0的起点,然后从这个起点出发使用dfs搜索所有能够到达的点,并且在搜索的时候使用一个全局变量来进行计数,一次dfs结束那么就将全局变量的值加入到结果集中(表明一个水域的结束),因为是二维矩阵的搜索,所以我们需要标记一下访问过的点,这样才不会导致对于已经访问过的点重新访问了,对于这道题目来说可以使用将矩阵中已经访问过的点标记为1即可,下一次就不会再访问了

② 对于搜索当前的起点能够到达的区域,我们可以使用一个二维列表来表示八个不同的方向,这样我们就可以在循环中依次尝试当前的点能够到达八个方向的哪些点,然后再递归下去

3. 代码如下:

from typing import List


class Solution:
    count = 0

    def dfs(self, land: List[List[int]], x: int, y: int, r: int, c: int, pos: List[List]):
        land[x][y] = 1
        self.count += 1
        # 搜索八个平行方向
        for i in range(8):
            x1, y1 = x + pos[i][0], y + pos[i][1]
            if 0 <= x1 < r and 0 <= y1 < c and land[x1][y1] == 0:
                self.dfs(land, x1, y1, r, c, pos)

    def pondSizes(self, land: List[List[int]]) -> List[int]:
        pos = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [1, -1], [-1, 1], [1, 1]]
        res = list()
        for i in range(len(land)):
            for j in range(len(land[0])):
                if land[i][j] == 0:
                    self.dfs(land, i, j, len(land), len(land[0]), pos)
                    res.append(self.count)
                    self.count = 0
        return sorted(res)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值