Leetcode Number of island I & II 解析 以及java实现

Leetcode Number of island I & II 解析 以及java实现

Number of island 是一道leetcode的经典BFS的题了,题目给一个二位的数组作为输入,1代表陆地,0代表海洋,如果陆地相连则是一个岛屿,让我们计算出当前数组内岛屿的数量。

思路:

大致思路就是我们先自己设定一个类用来存储坐标,在利用两个delta数组来存储位移的变量进行四方位移,然后利用BFS把岛屿进行合并,最后确定留下的岛屿都是不相连的就是我们最后得到的岛屿数量。

class Solution{
	class Coordinate{
		int x,y;
		public Coordiante(int a, int b){
			this.x = a;
			this.y = b;
		}
	}
	char ISLAND = '1';
	char WATER = '0';
	int[] deltaX = {1,0,0,-1};
	int[] dletaY = {0,1,-1,0};
	
	public int numIslands(char[][] gird){
		if(grid == null || grid.length == 0|| grid[0].length == 0){
            return 0;
        }
        int n = grid.length;
        int m = grid[0].length;
        int result = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m ;j++){
                if(grid[i][j]==ISLAND){
                    //System.out.printf("The x is %d, the y is %d\n",i,j);
                    markByBFS(grid,i,j);
                    result++;
                }
            }
        }
        return result;
	}
	
	protected void markByBFS(char[][] grid, int x, int y){
		Queue<Coordiante> queue = new LinkedList<>();
		queue.offer(new Coordiante(x,y));
		grid[x][y] = WATER;
		while(!queue.isEmpty()){
			Coordinate coor = queue.poll();
			for(int i = 0;i < 4;i++){
				Coordinate adj = new Coordiante(coor.x+deltaX[i],coor.y+deltaY[i]);
				if(inBound(adj,grid) == false)continue;
				if(grid[adj.x][adj.y]==ISLAND){
					queue.offer(adj):
					grid[adj.x][adj.y] = WATER;
				}
			}
		}
	}
	private boolean inBound(Coordinate adj,int[][] grid){
        if(adj.x < 0 || adj.x >= grid.length){
            return false;
        }
        if(adj.y < 0 || adj.y >= grid[0].length){
            return false;
        }
        return true;
    }
}

这一题相对来说还是比较简单的,我们只需要掌握BFS即可。

Number of Island ii

第二题则变得有一些特别了,一开始给与一个nxm大小的数组,里面都是水,然后按顺序添加陆地,每添加一块陆地都要返回一个当前的岛屿数量,这种情况如果继续使用BFS则会让时间复杂度变得很高,虽然说应该也是能过得,不过这里我们决定使用并查集得方法来解决这个问题。这里要注意得是我们要先压缩一下位置得表示,我们用n*x + y来把二位数组压缩成为一维得,这样我们就得到了一个id,利用这个id来进行并查集得合并与查找。

public Solution{
	public List<Integer> numOfIsland2(int n,int m, Point[] operators){
		List<Integer> res = new ArrayList<>();
        if(operators == null || operators.length == 0)return res;
        int cnt = 0;
        int[] roots = new int[m * n];
        Arrays.fill(roots,-1);
        int[] deltaX = {0,-1,1,0};
        int[] deltaY = {1,0,0,-1};

		for(Point point: operators){
			//压缩维度
			int id = m * point.x + point.y;
			if(roots[id] != -1){
				res.add(cnt);
				continue;
			}
			roots[id] = id;
			++cnt;
			for(int i = 0;i < 4;i++){
				int x = point.x + deltaX[i];
				int y = point.y + deltaY[i];
				int cur_id = m * x + y;
				// 越界检测
				if(x < 0 || x >= n || y < 0 || y >= m || roots[cur_id] == -1)continue;
                int p = findRoot(roots,cur_id);
                int q = findRoot(roots,id);
                if(p != q){
        			//合并并查集
                    roots[p] = q;
                    --cnt;
                }
            }
            res.add(cnt);
		}
		return res;
	}
	protected find(int[] roots, int id){
		return (id == roots[id])? id: find(roots,roots[id]);
	}
}

这样我们就可以解决这一道Number of island ii了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值