在问 · 算法题解

695. 岛屿的最大面积

题目描述

输入一个 m x n 的网格 grid,每个格子为 0(水)或 1(陆地)。网格外侧都视为水。

在上、下、左、右四个方向相邻的陆地格子连在一起,组成一座岛屿;斜对角不算相邻。一座岛屿的面积是它包含的陆地格子数。

返回面积最大的岛屿的面积。如果没有任何陆地,返回 0。

示例 1
输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6

解释:最大的岛有 6 个格子;斜向接触的格子不算同一座岛,所以不是 11。

示例 2
输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0

解释:网格中没有陆地。

数据范围

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1。

解题思路

逐格扫描。遇到 1 就从它出发做 DFS(用显式栈),把整座岛屿的格子一个个弹出并计数,同时把访问过的陆地改成 0,避免重复计算。一座岛搜索结束得到面积 area,用它更新最大值 best。

为什么正确

栈中的格子都已被改成 0 且尚未计数;每次弹出一个格子 area 恰好加 1,因此 DFS 结束时 area 就是整座岛的面积。

复杂度分析

时间 O(mn),每格最多入栈一次;空间 O(mn)(栈最坏情况)。

易错点

入栈时就要把格子改成 0;如果等到弹出时才改,同一个格子可能被多个邻居重复入栈,面积会被算多。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        best = 0
        for r in range(m):
            for c in range(n):
                if grid[r][c] == 1:
                    grid[r][c] = 0
                    stack = [(r, c)]
                    area = 0
                    while stack:
                        x, y = stack.pop()
                        area += 1
                        for nx, ny in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
                            if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 1:
                                grid[nx][ny] = 0
                                stack.append((nx, ny))
                    best = max(best, area)
        return best

载入编辑器,自己跑一遍 →

图论 专题的其他题目

查看 图论 全部题目 →