【LeetCode】岛屿数量 (DFS/BFS)

【LeetCode】岛屿数量 (DFS/BFS)

题目:
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [
[“1”,“1”,“1”,“1”,“0”],
[“1”,“1”,“0”,“1”,“0”],
[“1”,“1”,“0”,“0”,“0”],
[“0”,“0”,“0”,“0”,“0”] ]
输出:1

DFS
通过系统栈进行DFS(深度优先遍历)来完成,首先用一个HashSet来记录已经访问过的点,然后把每个没有访问过的’1’点做为根进行【上,下,左,右】方位(一条路走到黑!)的深度优先遍历,并用HashSet记录。因为要用到系统栈所以是递归,递归中的终止条件编写就很重要了!

public int numIslands(char[][] grid) {
		Set<Integer> set = new HashSet<Integer>();
		int sum=0;
		for(int i=0;i<grid.length;i++) {
			for(int j=0;j<grid[i].length;j++) {
				if(!set.contains(grid[i].length*i+j)&&grid[i][j]=='1') {
					sum++;
					DFS(set,grid,i,j);
				}
			}
		}
		return sum;
    }
	
	public void DFS(Set<Integer> s,char[][] grid,int i,int j){
		if(s.contains(grid[i].length*i+j)||grid[i][j]=='0')
			return ;
		s.add(grid[i].length*i+j);
		if(i-1>= 0)DFS(s,grid,i-1,j); //上
		if(i+1< grid.length)DFS(s,grid,i+1,j); //下
		if(j-1>= 0) DFS(s,grid,i,j-1); //左
		if(j+1< grid[i].length)DFS(s,grid,i,j+1); //右
		//return ;
	}

BFS
通过队列来实现BFS层次遍历,与DFS不同,BFS将下一层的数据【上,下,左,右】都添加到队列中。然后要注意剪枝问题(HashSet,HashMap…容器应用比较多)!

public int numIslands(char[][] grid) {
        if(grid==null||grid.length==0)
	    		return 0;
	    	Queue<Integer> queue = new LinkedList<Integer>();
	    	Set<Integer> set = new HashSet<Integer>();
	    	int size;
	    	int count=0;
	    	
	    	for(int i=0;i<grid.length;i++) {
	    		for(int j=0;j<grid[i].length;j++) {
	    			if(grid[i][j]=='1'&&!set.contains(i*grid[i].length+j)) {
	    				queue.add(i*grid[i].length+j);
	    				set.add(i*grid[i].length+j);
	    				count++;
	    				
	    				while(!queue.isEmpty()) {
	    					size =queue.size();
	    					for(int k=0;k<size;k++) {
	    						int target = queue.poll();
	    						int row = target/grid[i].length;
	    						int col = target%grid[i].length;
	    						
	    						int up = row -1;
	    						int down = row +1;
	    						int left = col -1;
	    						int right = col +1;
	    						
	    						if(up>=0&&grid[up][col]=='1'&&!set.contains(up*grid[i].length+col)) {
	    							queue.add(up*grid[i].length+col);
	    							set.add(up*grid[i].length+col);
	    						}
	    						if(down<grid.length&&grid[down][col]=='1'&&!set.contains(down*grid[i].length+col)) {
	    							queue.add(down*grid[i].length+col);
	    							set.add(down*grid[i].length+col);
	    						}
	    						if(left>=0&&grid[row][left]=='1'&&!set.contains(row*grid[i].length+left)) {
	    							queue.add(row*grid[i].length+left);
	    							set.add(row*grid[i].length+left);
	    						}
	    						if(right<grid[i].length&&grid[row][right]=='1'&&!set.contains(row*grid[i].length+right)) {
	    							queue.add(row*grid[i].length+right);
	    							set.add(row*grid[i].length+right);
	    						}
	    					}
	    				}
	    			}
	    		}
	    	}
            return count;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值