统计封闭岛屿的数目
问题描述:
有一个二维矩阵 grid ,每个位置要么是陆地(记号为 0 )要么是水域(记号为 1 )。
我们从一块陆地出发,每次可以往上下左右 4 个方向相邻区域走,能走到的所有陆地区域,我们将其称为一座「岛屿」。
如果一座岛屿完全由水域包围,即陆地边缘上下左右所有相邻区域都是水域,那么我们将其称为 「封闭岛屿」。
请返回封闭岛屿的数目。
示例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 区域包围)。
示例2:
输入: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
解题思路:
首先我们需要遍历整个岛屿,如果当前位置为0(陆地),我们就需要判断该位置所在的岛屿是否为封闭岛屿。dfs上下左右四个方向,如果四个方向全部都是陆地,则返回真,总数+1。(注意:dfs的时候需要把碰到陆地标记为水域,这样就可以避免下一次遍历的时候重复计算了)
此题不需要回溯,因为是求同一区域,不需要计算路径。扫描二维码关注公众号,回复: 10017795 查看本文章
图解:
第一次从左上角开始进入dfs
(1)变为1,并从四个方向dfs
(2)第一次返回0,并把陆地0都变成了水域1.
(3)当进入四周都是水域的陆地时,返回1
代码如下:
#include<iostream>
#include<vector>
using namespace std;
int dfs(int i,int j,vector<vector<int> >& grid){
if(i<0||j<0||i>=grid.size()||j>=grid[i].size()){//不满足条件
return 0;
}
if(grid[i][j]==1){//如果碰到水域返回1
return 1;
}
grid[i][j]=1;//如果碰到陆地则标记为水域
int x1= dfs(i+1,j,grid);
int x2= dfs(i-1,j,grid);
int y1= dfs(i,j+1,grid);
int y2= dfs(i,j-1,grid);
//四个方向全为水域返回1
if(x1&&x2&&y1&&y2){
return 1;
}
return 0;
}
int closedIsland(vector<vector<int> >& grid) {
int sum=0;
for(int i=1;i<grid.size()-1;i++){//边缘部分肯定不是岛屿,所以从1开始
for(int j=1;j<grid[i].size()-1;j++){
if(grid[i][j]==0){ //如果是陆地
if(dfs(i,j,grid)){
sum++;
}
}
}
}
return sum;
}
int main(){
vector<vector<int> > grid={{0,0,1,1,0,1,0,0,1,0},{1,1,0,1,1,0,1,1,1,0},{1,0,1,1,1,0,0,1,1,0},{0,1,1,0,0,0,0,1,0,1},{0,0,0,0,0,0,1,1,1,0},{0,1,0,1,0,1,0,1,1,1},{1,0,1,0,1,1,0,0,0,1},{1,1,1,1,1,1,0,0,0,0},{1,1,1,0,0,1,0,1,0,1},{1,1,1,0,1,1,0,1,1,0}};
cout<<closedIsland(grid);
return 0;
}