LeetCode 200.岛屿的数量

LeetCode 200.岛屿的数量

题目链接 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值