题目链接 https://leetcode-cn.com/problems/number-of-islands/
题目描述:
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:
1 1 1 1 0
1 1 0 1 0
1 1 0 0 0
0 0 0 0 0
输出: 1
示例 2:
输入:
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1
输出: 3
解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-islands
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
抓住一个点,只要他满足未越界,未访问,是岛屿,就在该点的基础上往四个方向不断搜索,搜索到符合条件的点,也按该规则继续往下搜索。。。
代码
DFS代码:
package test;
public class Demo88 {
public static void main(String[] args) {
}
// 方向数组
private static int[][] direction= {{-1,0},{0,-1},{1,0},{0,1}};
// 行
private int rows;
// 列
private int cols;
// 访问标志
private boolean[][] mark;
// 图
private char[][] grid;
public int numIslands(char[][] grid) {
rows=grid.length;//行
if(rows==0) {
return 0;
}
cols=grid[0].length;//列
this.grid=grid;
this.mark= new boolean[rows][cols];
int count=0;
for(int i=0;i<rows;i++) {
for(int j=0;j<cols;j++) {
if(!mark[i][j]&&grid[i][j]=='1') {
count++;
DFS(i,j);
}
}
}
return count;
}
public void DFS(int i, int j) {
// 标记为以访问
mark[i][j]=true;
// 往四个方向搜索
for(int k=0;k<4;k++) {
int nextX=i+direction[k][0];
int nextY=j+direction[k][1];
// 不越界,未访问,是岛屿
if(isArea(nextX,nextY)&&!mark[nextX][nextY]&&grid[nextX][nextY]=='1') {
DFS(nextX,nextY);
}
}
}
public boolean isArea(int x,int y) {
return x>=0&&x<rows&&y>=0&&y<cols;
}
}
BFS代码:
package test;
import java.util.LinkedList;
import java.util.Queue;
import org.omg.CORBA.PRIVATE_MEMBER;
public class Demo89 {
public static void main(String[] args) {
}
// 列
private int cols;
// 行
private int rows;
public int numIslands(char[][] grid) {
rows=grid.length;
if(rows==0) {
return 0;
}
cols=grid[0].length;
// 标记数组,访问过为true,未访问过false
boolean[][] marked=new boolean[rows][cols];
// 方向数组,表示 左、上、右、下
int[][] direction={{-1,0},{0,-1},{1,0},{0,1}};
// 计数器
int count=0;
for(int i=0;i<rows;i++) {
for(int j=0;j<cols;j++) {
// 如果该点满足未访问,且是岛屿
if(!marked[i][j]&&grid[i][j]=='1') {
// 岛屿数量加一
count++;
// 入队列
Queue<Integer> queue=new LinkedList<Integer>();
// "i*cols+j",是个小技巧,可以是加入的点转为数字入队
queue.offer(i*cols+j);
// 标记为以访问
marked[i][j]=true;
while(!queue.isEmpty()) {
// 出队
Integer cur = queue.poll();
// 小技巧的解析,恢复为点
int curX=cur/cols;
int curY=cur%cols;
// 将该点往四个方向搜索
for(int k=0;k<4;k++) {
int nextX=curX+direction[k][0];
int nextY=curY+direction[k][1];
// 如果四个方向上有满足不越界,未访问,是岛屿的,继续入队
if(isArea(nextX, nextY)&&!marked[nextX][nextY]&&grid[nextX][nextY]=='1') {
queue.offer(nextX*cols+nextY);
marked[nextX][nextY]=true;
}
}
}
}
}
}
return count;
}
// 判断是否越界
public boolean isArea(int x,int y) {
return x>=0&&x<rows&&y>=0&&y<cols;
}
}
标签:DFS,BFS