DFS之最大人工岛

Leetcode 827. 最大人工岛

在二维地图上, 0代表海洋, 1代表陆地,我们最多只能将一格 0 海洋变成 1变成陆地。

进行填海之后,地图上最大的岛屿面积是多少?(上、下、左、右四个方向相连的 1 可形成岛屿)

示例 1:

输入: [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。

示例 2:

输入: [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。

示例 3:

输入: [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。

说明:

1 <= grid.length = grid[0].length <= 50
0 <= grid[i][j] <= 1

方法一:深度优先搜索【超时】

对于每个 0,将它变成 1,然后做一次深度优先搜索计算出连通块的大小。答案就是找到的最大连通块。如果没有 0,那么答案就是整个网格的大小。
时间复杂度:O(N^4),其中 N 是 grid 的长和宽。
空间复杂度:O(N^2),深度优先搜索需要的 stack 和 seen 的空间。

方法二:连通块大小【通过】

再上一个解法中,我们检查了每个 0。然而,我们也计算了每个组的大小,所以其实并不需要利用深度优先搜索重复计算所有的连通块。
我们可以通过记录连通块编号来解决这个问题,不同的连通块编号不同。这样,我们就可以累加不同编号的连通块面积和。

对于每个连通块,将所有格点赋值为 index 并记录他们的大小 area[index] = dfs(...)
然后对于每个 0,查看周围的邻居编号在 seen 并将这个区域的大小加入结果,改变 seen 的值。这就是当前节点的面积大小,在其中找到最大的。

为了解决没有 0 的情况,我们只需要记录之前计算的最大面积并输出即可。

class Solution:
    def largestIsland(self, grid: List[List[int]]) -> int:
        n = len(grid)
        m = len(grid[0])
        area = {} # 记录每一个连通块的面积
        
        index = 2 # 为了避免和原始的1冲突,连通块标记从2开始
        for row in range(n):
            for col in range(m):
            	# 对连通块进行dfs遍历
            	# 每次遍历,把其周围的1进行index标记,同时记录连通块的面积
                if grid[row][col] == 1:
                    area[index] = self.dfs(grid, row, col, index)
                    index += 1
                    
        ans = max(area.values() or [0]) # 防止全为0
        
        for row in range(n):
            for col in range(m):
                if grid[row][col] == 0: # 对于每一个0,寻找其周围的连通块
                    visited = set() # 注意visited的位置
                    for x, y in [(row - 1, col), (row + 1, col), (row, col - 1), (row, col + 1)]:
                        if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] > 1:
                            visited.add(grid[x][y])
                    # 更新最大面积,如果0周围存在连通块,
                    # 那么最大面积等于周围连通块面积和+1
                    ans = max(ans, 1 + sum(area[index] for index in visited))  
        return ans

	# dfs遍历,对其周围为1的元素进行标记,并记录面积大小
    def dfs(self, grid, row, col, index):
        area = 1
        grid[row][col] = index
        for x, y in [(row - 1, col), (row + 1, col), (row, col - 1), (row, col + 1)]:
            if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] == 1:
                area += self.dfs(grid, x, y, index)
        return area

时间复杂度:O(N^2),其中 N 是 grid 的长度和宽度。
空间复杂度:O(N^2),深度优先搜索需要的数组 area 的额外空间。

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页