leetcode200. Number of Islands(DFS,BFS,UnionFound)

独立连通分量的个数:

 class Solution {
    	private char[][] grid;
        public int numIslands(char[][] grid) {
            if(grid.length==0){
                return 0;
            }
            this.grid=grid;
            int m=grid.length;
            int n=grid[0].length;
           // //开发出发并标记DFS或BFS
           // int count=0;
           // for(int i=0;i<m;i++){
           // 	for(int j=0;j<n;j++){
           // 		if(grid[i][j]=='1'){//未访问过的新大陆的起点
           // 			searchWithDFS(i, j);
           // 			count++;
           // 		}
           // 	}
           // }
           //  return count;
           UnionFound unionFound=new UnionFound(grid);
           int[][] directions=new int[][]{{1,0},{0,1},{-1,0},{0,-1}};//下右上左
           for(int i=0;i<m;i++){
               for(int j=0;j<n;j++){
                   if(grid[i][j]=='1'){
                       for(int k=0;k<=3;k++){
                           int x=i+directions[k][0];
                           int y=j+directions[k][1];
                           if(x<0 || x==grid.length || y<0 || y==grid[0].length || grid[x][y]!='1'){//看能否union到相邻的土地上
                               continue;
                           }
                           unionFound.union(i*n+j, x*n+y);
                       }
                   }
               }
           }
           return unionFound.count;
        }
        //1.用深度优先找从i,j位置可以到达的所有位置,i,j是一个可达点。
        public void searchWithDFS(int i,int j){
        	grid[i][j]='0';//key
        	int[][] directions=new int[][]{{1,0},{0,1},{-1,0},{0,-1}};//下右上左
        	for(int k=0;k<=3;k++){
        		int x=i+directions[k][0];
        		int y=j+directions[k][1];
        		if(x<0 || x==grid.length || y<0 || y==grid[0].length || grid[x][y]=='0'){
        			continue;
        		}
        		searchWithDFS(x,y);
        	}
        }
        //2.用广度优先从(i,j)进行搜索
        private class Cell{
        	int row;
        	int col;
        	public Cell(int i,int j){
        		row=i;
        		col=j;
        	}
        }
        public void searchWithBFS(int i,int j){
        	Queue<Cell> queue=new LinkedList<Cell>();
        	queue.add(new Cell(i,j));
        	grid[i][j]='0';
        	int[][] directions=new int[][]{{1,0},{0,1},{-1,0},{0,-1}};//下右上左
        	while(!queue.isEmpty()){
        		Cell start=queue.poll(); 
            	for(int k=0;k<=3;k++){
            		int x=start.row+directions[k][0];
            		int y=start.col+directions[k][1];
            		if(x<0 || x==grid.length || y<0 || y==grid[0].length || grid[x][y]=='0'){
            			continue;
            		}
            		queue.add(new Cell(x,y));
            		grid[x][y]='0';
            	}
        	}
        }
        //用并查集,id=i*grid[0].length+j,约定id值最小的结点作为整的岛屿的头目
        private class UnionFound{
        	private int[] fathers;
        	private int count;//目前独立块个数
        	public UnionFound(char[][] grid){
        		fathers=new int[grid.length*grid[0].length];
        		count=0;
        		for(int i=0;i<grid.length;i++){
        			for(int j=0;j<grid[0].length;j++){
        				if(grid[i][j]=='1'){//先每个节点独立做头
        					fathers[i*grid[0].length+j]=i*grid[0].length+j;
        					count++;
        				}
        			}
        		}
        	}
        	//找一个id的根源
        	private int found(int id){
        		while(fathers[id]!=id){
        			id=fathers[id];
        		}
    			return id;
        	}
        	public  void union(int id1,int id2){
        		int father1=found(id1);//找id1的爸爸
        		int father2=found(id2);//找id2的爸爸
        		if(father1<father2){//把father2指向father1
        			fathers[father2]=father1;
        			count--;//独立块个数减1
        		}else if(father2<father1){//把father1指向father2
        			fathers[father1]=father2;
        			count--;//独立块个数减1
        		}
        		//若father1==father2,说明两个结点同根,不用改
        	}
        }
}

695.求最大岛屿面积

class Solution {
    	private int[][] grid;
        public int maxAreaOfIsland(int[][] grid) {
            if(grid.length==0){
            	return 0;
            }
            int m=grid.length;
            int n=grid[0].length;
            this.grid=grid;
            int maxArea=0;
            for(int i=0;i<m;i++){
            	for(int j=0;j<n;j++){
            		if(grid[i][j]==1){
            			maxArea=Math.max(maxArea, areaWithBFS(i*grid[0].length+j));
            		}
            	}
            }
            return maxArea;
        }
        //用深度优先找(i,j)所在岛屿的面积
        public int areaWithDFS(int i,int j){
        	int area=1;
        	grid[i][j]=0;
        	int[][] directions=new int[][]{{1,0},{0,1},{-1,0},{0,-1}};//下右上左
        	for(int k=0;k<=3;k++){
        		int x=i+directions[k][0];
        		int y=j+directions[k][1];
        		if(x<0 || x==grid.length || y<0 || y==grid[0].length || grid[x][y]!=1){
        			continue;
        		}
        		area+=areaWithDFS(x, y);
        	}
        	return area;
        }
        //用广度优先找(i,j)所在岛屿的面积。用i*grid[0].length+j来唯一表示一个位置
        //notice.入队的时候改book
        public int areaWithBFS(int pos){
        	Queue<Integer> queue=new LinkedList<Integer>();
        	grid[pos/grid[0].length][pos%grid[0].length]=0;//表示已经访问过或者已经在访问队列
        	queue.add(pos);
        	int[][] directions=new int[][]{{1,0},{0,1},{-1,0},{0,-1}};//下右上左
        	int area=0;
        	while(!queue.isEmpty()){
        		int curPos=queue.poll();
        		int i=curPos/grid[0].length;
        		int j=curPos%grid[0].length;
        		area++;
        		for(int k=0;k<=3;k++){
        			int x=i+directions[k][0];
        			int y=j+directions[k][1];
        			if(x<0 || x==grid.length || y<0 || y==grid[0].length || grid[x][y]!=1){
        				continue;
        			}
        			grid[x][y]=0;
        			queue.add(x*grid[0].length+y);
        		}
        	}
        	return area;
        }      
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值