leetcode —— 面试题 16.19. 水域大小

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pond-sizes-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
————————

1、广度优先遍历:

(1)将数组从左往右,从上往下进行遍历,当遇到一个数据是0,即表示海洋时,将该位置放进队列中;初始化一个变量nums,表示以该位置为起点的海洋面积有多大,初始值为nums=1;同时切记将当前位置的海洋的值从0改为-1,表示已经搜索过;
(2)遍历队列,对队列中的每个位置,判断其左上,上,右上,左,右,左下,下,右下八个位置是否是海洋,如果是海洋,则将其位置信息放进队列中,并使num的值加一;同时切记将其海洋值从0变为-1,表示其已经搜索过;
(3)当队列为空时,表示与当前位置相连的海洋已经寻找完毕,将得到的nums值放进一个列表中;这时候需要去寻找下一个点,重复上面(1)-(3)的操作,直到对整个地图搜索完毕;

具体Python代码如下:

class Solution:
    def pondSizes(self, land: List[List[int]]) -> List[int]:
        rows,cols = len(land),len(land[0])  # 计算行数和列数
        if rows==0 or cols==0:
            return []
        
        def neighbor(i,j):    # 用于寻找当前位置land[i][j]的周围所有数据中是否存在海洋,如果存在则返回其坐标信息
            for nr,nc in [[i-1,j],[i+1,j],[i,j-1],[i,j+1],[i-1,j-1],[i-1,j+1],[i+1,j-1],[i+1,j+1]]:
                if 0<=nr<rows and 0<=nc<cols and land[nr][nc]==0:
                    yield nr,nc
                    
        max_num = []    # 用于存储所有池塘的面积
        queue = collections.deque()   # 队列,用于广度优先遍历
        
        for i in range(rows):    #  遍历整个地图
            for j in range(cols):
                if land[i][j] == 0:    # 发现海洋点
                    queue.append([i,j])    # 将当前海洋位置放进队列中
                    land[i][j] = -1    # 将当前海洋的数据从0变为-1,表示已经搜索过
                    num = 1    # 当前海洋面积的大小为1
                    while queue:    # 遍历当前海洋的周围所有邻居的情况
                        nr,nc = queue.popleft()    
                        for ii,jj in neighbor(nr,nc):    #  使用上面定义的生成器函数    
                            land[ii][jj] = -1    # 找到l周围的海洋,并将其值变为-1,表示已经搜索过
                            queue.append([ii,jj])    # 将其放进队列中,用于下一步的广度优先遍历
                            num += 1    # 当其周围有一个海洋时,池塘的面积需要加1
                    max_num.append(num)      # 将当前位置的池塘面积大小放进队列中      
        return sorted(max_num)
                    

2、深度优先遍历

(1)将数组从左往右,从上往下进行遍历,当遇到land[i][j]=0时表示遇到海洋,基于land[i][j]遍历其周围所有的点。深度优先遍历和广度优先遍历不同,广度优先遍历使用队列,遍历时一圈一圈往外遍历。而深度优先遍历时当在某点周围遇到海洋点时,基于该海洋点再搜索周围的点,如果再找到则一直深究下去。

其Python代码如下:

class Solution:
    def pondSizes(self, land: List[List[int]]) -> List[int]:
        rows,cols = len(land),len(land[0])
        if rows==0 or cols==0:
            return []
        
        def neighbor(i,j):   #  用于遍历某点周围的所有点是否是海洋点
            for nr,nc in [[i-1,j],[i+1,j],[i,j-1],[i,j+1],[i-1,j-1],[i-1,j+1],[i+1,j-1],[i+1,j+1]]:
                if 0<=nr<rows and 0<=nc<cols and land[nr][nc]==0:
                    yield nr,nc
                    
        def dfs(i,j):    # 深度遍历函数
            area = 1
            land[i][j] = 1    # 修改已经遍历过的海洋点
            for nr,nc in neighbor(i,j):    # 对land[i][j]的周围进行遍历,找到海洋点
                area += dfs(nr,nc)    
            return area
                    
        max_num = []    # 用于存储不同的池塘面积
        
        for i in range(rows):    # 遍历整个地图
            for j in range(cols):
                if land[i][j] == 0:    # 遇到海洋点
                    max_num.append(dfs(i,j))    # dfs()函数返回以包括land[i][j]的池塘面积
        
        return sorted(max_num)    # 进行排序
发布了320 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37388085/article/details/105206895