文章摘要:
- 题目要求计算给定二进制矩阵中最大岛屿的面积,岛屿由相邻的1(陆地)组成,相邻指水平或垂直方向的四个方向。通过深度优先搜索(DFS)遍历矩阵,标记已访问的陆地并统计每块岛屿的面积,最终返回最大面积。代码实现包括全局变量定义、DFS函数递归搜索及主函数遍历矩阵,时间复杂度为O(mn),空间复杂度为O(mn)。
文章目录
题目链接:695. 岛屿的最大面积
一、题目解析
题目给出一个大小为 m x n 的二进制矩阵 grid。
岛屿 是由一些相邻的 1(陆地)组成的,这里的 『相邻』是指必须在 水平或者竖直的四个方向上 相邻。
假设 grid 的四个边缘都被 0(水)包围着。
岛屿的面积是指 1(陆地)方格的数目。
我们需要计算并返回 grid 中最大的岛屿面积。如果没有岛屿,就返回 0。
下面给出示例:
#mermaid-svg-Td6YSX7Y3MxlDq35{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Td6YSX7Y3MxlDq35 .error-icon{fill:#552222;}#mermaid-svg-Td6YSX7Y3MxlDq35 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Td6YSX7Y3MxlDq35 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .marker.cross{stroke:#333333;}#mermaid-svg-Td6YSX7Y3MxlDq35 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Td6YSX7Y3MxlDq35 p{margin:0;}#mermaid-svg-Td6YSX7Y3MxlDq35 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .cluster-label text{fill:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .cluster-label span{color:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .cluster-label span p{background-color:transparent;}#mermaid-svg-Td6YSX7Y3MxlDq35 .label text,#mermaid-svg-Td6YSX7Y3MxlDq35 span{fill:#333;color:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .node rect,#mermaid-svg-Td6YSX7Y3MxlDq35 .node circle,#mermaid-svg-Td6YSX7Y3MxlDq35 .node ellipse,#mermaid-svg-Td6YSX7Y3MxlDq35 .node polygon,#mermaid-svg-Td6YSX7Y3MxlDq35 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .rough-node .label text,#mermaid-svg-Td6YSX7Y3MxlDq35 .node .label text,#mermaid-svg-Td6YSX7Y3MxlDq35 .image-shape .label,#mermaid-svg-Td6YSX7Y3MxlDq35 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Td6YSX7Y3MxlDq35 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .rough-node .label,#mermaid-svg-Td6YSX7Y3MxlDq35 .node .label,#mermaid-svg-Td6YSX7Y3MxlDq35 .image-shape .label,#mermaid-svg-Td6YSX7Y3MxlDq35 .icon-shape .label{text-align:center;}#mermaid-svg-Td6YSX7Y3MxlDq35 .node.clickable{cursor:pointer;}#mermaid-svg-Td6YSX7Y3MxlDq35 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .arrowheadPath{fill:#333333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Td6YSX7Y3MxlDq35 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Td6YSX7Y3MxlDq35 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Td6YSX7Y3MxlDq35 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Td6YSX7Y3MxlDq35 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .cluster text{fill:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 .cluster span{color:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Td6YSX7Y3MxlDq35 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Td6YSX7Y3MxlDq35 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Td6YSX7Y3MxlDq35 .icon-shape,#mermaid-svg-Td6YSX7Y3MxlDq35 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Td6YSX7Y3MxlDq35 .icon-shape p,#mermaid-svg-Td6YSX7Y3MxlDq35 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Td6YSX7Y3MxlDq35 .icon-shape .label rect,#mermaid-svg-Td6YSX7Y3MxlDq35 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Td6YSX7Y3MxlDq35 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Td6YSX7Y3MxlDq35 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Td6YSX7Y3MxlDq35 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-Td6YSX7Y3MxlDq35 .blue>*{fill:#3498db!important;stroke:#333!important;stroke-width:1px!important;color:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .blue span{fill:#3498db!important;stroke:#333!important;stroke-width:1px!important;color:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .blue tspan{fill:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .yellow>*{fill:#f39c12!important;stroke:#333!important;stroke-width:1px!important;color:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .yellow span{fill:#f39c12!important;stroke:#333!important;stroke-width:1px!important;color:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .yellow tspan{fill:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .orange>*{fill:#e67e22!important;stroke:#333!important;stroke-width:1px!important;color:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .orange span{fill:#e67e22!important;stroke:#333!important;stroke-width:1px!important;color:white!important;}#mermaid-svg-Td6YSX7Y3MxlDq35 .orange tspan{fill:white!important;} R7
0
0
0
0
0
0
0
1
1
0
0
0
0
R6
0
0
0
0
0
0
0
1
1
1
0
0
0
R5
0
0
0
0
0
0
0
0
0
0
1
0
0
R4
0
1
0
0
1
1
0
0
1
1
1
0
0
R3
0
1
0
0
1
1
0
0
1
0
1
0
0
R2
0
1
1
0
1
0
0
0
0
0
0
0
0
R1
0
0
0
0
0
0
0
1
1
1
0
0
0
R0
0
0
1
0
0
0
0
1
0
0
0
0
0
返回 6 即可。
二、算法原理 + 代码实现
我们的思路依然是 深度优先遍历:
- 遍历矩阵找到没被标记过的陆地(1),找到之后就以该位置为起点向上、下、左、右四个方向开始 DFS
- 在 DFS 时,用一个变量记录 "岛屿面积大小"(即1的个数);在某个位置开始 DFS 前先将该位置标记更新以下防止后面重复访问
- 当一个位置的 DFS 遍历完毕,更新结果(记录最大面积的变量)
- 当矩阵遍历完毕,返回记录最大面积的变量即可
全局变量
将二维矩阵 grid 改成全局变量以便递归操作;布尔类型的数组 visit 用于标记二维矩阵中的特定位置的状态:false 表示未被标记的;m 和 n 表示二维矩阵的大小;countArea 记录一块岛屿的面积;ret 记录最大岛屿的面积。
java
int[][] gird;
boolean[][] visit;
int m, n, countArea, ret;
int[] dx = {0, 0, -1, 1};
int[] dy = {-1, 1, 0, 0};
dfs 函数
函数头
dfs 函数的任务是 从特定的位置开始往上、下、左、右四个方向寻找未被标记的陆地(1) ,因此 参数是某个位置的坐标。
java
dfs(int row, int col);
函数体
进入 dfs 函数的第一件事是 先统计陆地面积(即 countArea 自增1) ,然后 更新当前位置 〖row, col〗的状态为 true,表示该陆地已经被标记过。
细节问题
递归出口
本题只需要将矩阵遍历完毕之后,返回 ret 的值即可,无需手动设置递归出口。
代码实现
java
class Solution {
int[][] gird;
boolean[][] visit;
int m, n, countArea, ret;
int[] dx = {0, 0, -1, 1};
int[] dy = {-1, 1, 0, 0};
public int maxAreaOfIsland(int[][] givenGrid) {
gird = givenGrid; m = gird.length; n = gird[0].length;
visit = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (gird[i][j] == 1 && !visit[i][j]) {
// 发现未被标记的陆地
countArea = 0;
dfs(i, j);
// 更新结果
ret = Math.max(ret, countArea);
}
}
}
return ret;
}
private void dfs(int row, int col) {
// 更新面积
countArea++;
// 标记陆地状态
visit[row][col] = true;
for (int k = 0; k < 4; k++) {
int x = row + dx[k], y = col + dy[k];
if (x >= 0 && x < m && y >= 0 && y < n) {
if (gird[x][y] == 1 && !visit[x][y]) {
// 在指定位置的x,y位置方向发现未被标记的陆地
dfs(x, y);
}
}
}
}
}
完