floodfill问题——飞地的数量
问题描述
给出一个二维数组 A,每个单元格为 0(代表海)或 1(代表陆地)。
移动是指在陆地上从一个地方走到另一个地方(朝四个方向之一)或离开网格的边界。
返回网格中无法在任意次数的移动中离开网格边界的陆地单元格的数量。
示例 1:
输入:[[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出:3
解释:
有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。
示例 2:
输入:[[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
输出:0
解释:
所有 1 都在边界上或可以到达边界。
提示:
1 <= A.length <= 500
1 <= A[i].length <= 500
0 <= A[i][j] <= 1
所有行的大小都相同
思路
遍历二维数组,碰到1就dfs四联通/八联通,都是一个套路
代码
public class NumOfEnclaves {
int[][] g;
int num;//存储有几块飞地
int sum;//存储每一次dfs的陆地数量
boolean containsBorder;
public int numEnclaves(int[][] grid) {
if(null==grid||grid.length==0) return 0;
g = 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){
dfs(i,j);
//飞地+1
if(!containsBorder){
num++;
ans+=sum;
}
sum = 0;
containsBorder = false;
}
}
}
return ans;
}
private void dfs(int i,int j){
if(i==0||i==g.length-1||j==0||j==g[0].length-1){
containsBorder = true;
}
sum++;
g[i][j] = 0;
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
if(dx==0||dy==0){
int nx = i+dx;
int ny = j+dy;
if(nx>=0&&nx<g.length&&ny>=0&&ny<g[0].length&&g[nx][ny]==1){
dfs(nx,ny);
}
}
}
}
}
public static void main(String[] args) {
System.out.println(new NumOfEnclaves().numEnclaves(new int[][]{{0,0,0,0,0}, {0,1,0,0,0}, {0,0,1,1,0}, {0,0,1,0,1},{0,1,0,0,1}}));
}
}