岛屿问题(岛数量/孤岛/面积/周长)
Posted yangbocsu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了岛屿问题(岛数量/孤岛/面积/周长)相关的知识,希望对你有一定的参考价值。
岛屿问题
200. 岛屿数量
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
参考代码
class Solution
public int numIslands(char[][] grid)
int ans = 0;
int m = grid.length;
int n = grid[0].length;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(grid[i][j] =='1')
ans ++;
dfs(grid,i,j);
return ans;
void dfs(char[][] grid, int i, int j)
int m = grid.length;
int n = grid[0].length;
if(i < 0 || i >= m || j < 0 || j>=n)
// 超出边界
return;
if(grid[i][j] !='1')
return ;// 已经是海水了
grid[i][j] = '2'; // 将 (i, j) 变成海水
// 淹没上下左右的陆地
dfs(grid,i+1,j);
dfs(grid,i-1,j);
dfs(grid,i,j+1);
dfs(grid,i,j-1);
1254. 统计封闭岛屿的数目
二维矩阵 grid 由 0 (土地)和 1 (水)组成。岛是由最大的4个方向连通的 0 组成的群,封闭岛是一个 完全 由1包围(左、上、右、下)的岛。
请返回 封闭岛屿 的数目。
输入:grid = [
[1,1,1,1,1,1,1,0],
[1,0,0,0,0,1,1,0],
[1,0,1,0,1,1,1,0],
[1,0,0,0,0,1,0,1],
[1,1,1,1,1,1,1,0]]
输出:2
解释:
灰色区域的岛屿是封闭岛屿,因为这座岛屿完全被水域包围(即被 1 区域包围)。
输入:grid = [
[0,0,1,0,0],
[0,1,0,1,0],
[0,1,1,1,0]]
输出:1
输入:grid = [[1,1,1,1,1,1,1],
[1,0,0,0,0,0,1],
[1,0,1,1,1,0,1],
[1,0,1,0,1,0,1],
[1,0,1,1,1,0,1],
[1,0,0,0,0,0,1],
[1,1,1,1,1,1,1]]
输出:2
参考代码
class Solution
public int closedIsland(int[][] grid)
int m = grid.length;
int n = grid[0].length;
// 将左边界和右边界 淹没
for(int i = 0; i < m; i++)
dfs(grid,i,0); // 把靠左边的岛屿淹掉
dfs(grid,i,n-1); // 把靠下边的岛屿淹掉
// 将上边界和下边界烟波
for(int j = 0; j < n; j++)
dfs(grid,0,j); // 把靠上边的岛屿淹掉
dfs(grid,m-1,j); // 把靠下边的岛屿淹掉
int ans = 0;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(grid[i][j] == 0)
ans ++;
dfs(grid,i,j);
return ans;
public void dfs(int[][] grid,int i,int j)
if(i < 0 || i >= grid.length || j<0 || j>=grid[0].length)
return;
// 已经是海水了
if(grid[i][j] == 1)
return ;
//将 (i, j) 变成海水
grid[i][j] = 1;
dfs(grid,i,j-1);
dfs(grid,i,j+1);
dfs(grid,i-1,j);
dfs(grid,i+1,j);
本题与岛屿数量的区别在于 边界上的岛屿不算岛屿,因为题目要求统计封闭岛屿的数目,这点注意了,代码就出来了。
class Solution
int val = 0;
public int closedIsland(int[][] grid)
int m = grid.length;
int n = grid[0].length;
// // 将左边界和右边界 淹没
// for(int i = 0; i < m; i++)
// dfs(grid,i,0); // 把靠左边的岛屿淹掉
// dfs(grid,i,n-1); // 把靠下边的岛屿淹掉
//
// // 将上边界和下边界烟波
// for(int j = 0; j < n; j++)
// dfs(grid,0,j); // 把靠上边的岛屿淹掉
// dfs(grid,m-1,j); // 把靠下边的岛屿淹掉
//
int ans = 0;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(grid[i][j] == 0)
val = 1;
dfs(grid,i,j);
ans += val;
return ans;
public void dfs(int[][] grid,int i,int j)
if(i < 0 || i >= grid.length || j<0 || j>=grid[0].length)
val = 0;
return;
// 已经是海水了
if(grid[i][j] == 1)
return ;
//将 (i, j) 变成海水
grid[i][j] = 1;
dfs(grid,i,j-1);
dfs(grid,i,j+1);
dfs(grid,i-1,j);
dfs(grid,i+1,j);
695. 岛屿的最大面积
给你一个大小为 m x n 的二进制矩阵 grid 。
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。
输入: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
解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1 。
参考代码
class Solution
public int maxAreaOfIsland(int[][] grid)
int ans = 0;
for(int i = 0; i < grid.length; i++)
for(int j = 0 ; j < grid[0].length; j++)
if(grid[i][j] == 1)
int tempArea = area(grid,i,j);
ans = Math.max(ans,tempArea);
return ans;
public int area(int[][] grid, int i ,int j)
// 数组下标到边界到,再走就要越界了。
if( i<0 || i>=grid.length || j<0 || j>=grid[0].length )
return 0;
// 关于|| 和 && 的说明,你是越界,越界的话,有多种可能,只要其中一种满足就可以了。
// && 是必须在四个边界之内
// 如果遇到的不是岛屿,也直接返回
if(grid[i][j] != 1)
return 0;
// 到这里,这格就是岛屿了 grid[i][j] == 1
grid[i][j] = 2; // 但是,我要加面积,你给我把这格变为2了,所以下面就是 1 +
return 1
+ area(grid,i,j-1)
+ area(grid,i,j+1)
+ area(grid,i+1,j)
+ area(grid,i-1,j);
// 判断坐标 (r, c) 是否在网格中
public boolean inArea(int[][] grid, int i, int j)
return i>=0 && i < grid.length && j>=0 && j < grid[0].length;
463. 岛屿的周长
给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
参考代码
class Solution
public int islandPerimeter(int[][] grid)
int ans= 0;
first:for(int i = 0; i < grid.length; i++)
for(int j = 0; j < grid[0].length; j++)
if(grid[i][j] == 1)
ans = dfs(grid,i,j);
break first;
return ans;
public int dfs(int[][] grid, int i ,int j)
// 遇到边界时,就是一边的长
if( i<0 || i >= grid.length || j<0 || j>=grid[0].length)
return 1;
// 遇到海洋 grid[i][j] == 0 也算是要一边的长
if(grid[i][j] == 0)
return 1;
//
if(grid[i][j] == 2)
return 0;
grid[i][j] = 2;
return dfs(grid,i,j-1) + dfs(grid,i,j+1) 岛屿问题(岛数量/孤岛/面积/周长)