🏝️ 岛屿的最大面积
📝 题目描述
给你一个大小为m x n
的二进制矩阵grid
。
岛屿是由一些相邻的 grid
的四个边缘都被
岛屿的面积是岛上值为
计算并返回grid
中最大的岛屿面积。如果没有岛屿,请返回面积为
📋 代码模板
class Solution {
public int maxAreaOfIsland(int[][] grid) {
}
}
function maxAreaOfIsland(grid: number[][]): number {
}
💡 提示
为 或
🚀 示例
示例一
输入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
。下图展示了网格中各个岛屿的面积。
示例二
输入grid
为[[1,1,1,0,0,1],[1,1,0,1,0,0],[0,0,0,1,1,0],[0,1,1,1,0,1]]
,输出为6
。下图展示了网格中各个岛屿的面积。
示例三
输入grid
为[[0,0,0,0,0,0,0,0]]
,输出为0
,这是因为网格图中不存在岛屿。
🖊️ 题解
该题本质上是在网格中找各个连通块的大小,并取最大值作为答案。
我们可以初始化一个值为 DFS
或BFS
。在搜索过程中,每遇到一个尚未访问过的陆地单元格(值为
为了进一步节省算法的空间,我们可以直接将网格中单元格的值更新为
DFS
class Solution {
private final static int[][] DIRS = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
private final static int VISITED = 2;
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length, n = grid[0].length;
int maxArea = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
maxArea = Math.max(maxArea, dfs(grid, i, j));
}
}
}
return maxArea;
}
private int dfs(int[][] grid, int i, int j) {
if (i < 0 || i > grid.length - 1 || j < 0 || j > grid[0].length - 1
|| grid[i][j] != 1) {
return 0;
}
grid[i][j] = VISITED;
int area = 1;
for (int d = 0; d < 4; d++) {
area += dfs(grid, i + DIRS[d][0], j + DIRS[d][1]);
}
return area;
}
}
const DIRS: number[][] = [[-1, 0], [1, 0], [0, -1], [0, 1]];
const VISITED = 2;
function maxAreaOfIsland(grid: number[][]): number {
const m = grid.length, n = grid[0].length;
const dfs = (i: number, j: number): number => {
if (i < 0 || i > m - 1 || j < 0 || j > n - 1 || grid[i][j] != 1) {
return 0;
}
grid[i][j] = VISITED;
let area = 1;
for (let d = 0; d < 4; d++) {
area += dfs(i + DIRS[d][0], j + DIRS[d][1]);
}
return area;
}
let maxArea: number = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
maxArea = Math.max(maxArea, dfs(i, j));
}
}
}
return maxArea;
}
BFS
class Solution {
private final static int[][] DIRS = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
private final static int VISITED = 2;
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length, n = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
int maxArea = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
int area = 1;
queue.offer(new int[]{i, j});
grid[i][j] = VISITED;
while (!queue.isEmpty()) {
int[] cell = queue.poll();
int oldI = cell[0], oldJ = cell[1];
for (int d = 0; d < 4; d++) {
int currentI = oldI + DIRS[d][0], currentJ = oldJ + DIRS[d][1];
if (currentI >= 0 && currentI < m && currentJ >= 0 && currentJ < n
&& grid[currentI][currentJ] == 1) {
area++;
queue.offer(new int[]{currentI, currentJ});
grid[currentI][currentJ] = VISITED;
}
}
}
maxArea = Math.max(maxArea, area);
}
}
}
return maxArea;
}
}
const DIRS: number[][] = [[-1, 0], [1, 0], [0, -1], [0, 1]];
const VISITED = 2;
function maxAreaOfIsland(grid: number[][]): number {
const m = grid.length, n = grid[0].length;
const queue: number[][] = [];
let maxArea = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
let area = 1;
queue.push([i, j]);
grid[i][j] = VISITED;
while (queue.length > 0) {
const cell: number[] = queue.shift()!;
const oldI = cell[0], oldJ = cell[1];
for (let d = 0; d < 4; d++) {
const currentI = oldI + DIRS[d][0], currentJ = oldJ + DIRS[d][1];
if (currentI >= 0 && currentI < m && currentJ >= 0 && currentJ < n
&& grid[currentI][currentJ] == 1) {
area++;
queue.push([currentI, currentJ]);
grid[currentI][currentJ] = VISITED;
}
}
}
maxArea = Math.max(maxArea, area);
}
}
}
return maxArea;
}
💭 复杂度分析
基于DFS
的解决方案的复杂度分析如下。
- 时间复杂度:
。其中 与 分别为网格的行数和列数。 - 空间复杂度:
。在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到 。
基于BFS
的解决方案的复杂度分析如下。
- 时间复杂度:
。其中 与 分别为网格的行数和列数。 - 空间复杂度:
。