LeetCode ---- 200. 岛屿数量 (java)

 

 

方法: 广度优先搜索 

线性扫描整个二维网格,如果一个结点包含 1,则以其为根结点启动广度优先搜索。将其放入队列中,(方法一改变原来的网格:并将值设为 0 以标记访问过该结点;方法二不改变原来网格:新开一个二维数组保存是否访问该结点)。迭代地搜索队列中的每个结点,直到队列为空。

 

我这边做法是新开一个二维数组保存是否访问该节点。

package xxxx;

import java.util.LinkedList;
import java.util.Queue;

/**
 * create by ziqiiii
 */
public class Test {
    static public void main(String[] args) {
        int[][] area = {
                {0,1,1,0,1,0,0},
                {1,0,0,1,1,1,0},
                {1,1,0,0,1,1,0},
                {0,1,1,0,0,1,1}
        };
        System.out.println(findIslandNums(area)); // 3


        int[][] area2 = {
                {0,1,1,0,1,0,0},
                {1,0,0,1,0,1,0},
                {1,1,0,0,1,1,0},
                {0,1,1,0,0,1,1}
        };
        System.out.println(findIslandNums(area2)); //5


        int[][] area3 = {{}};
        System.out.println(findIslandNums(area3)); //0

        int[][] area4 = {
                {1,0,1,0},
                {1,1,1,0},
                {0,0,1,1},
                {1,0,1,0},
                {1,1,1,1}
        };
        System.out.println(findIslandNums(area4));//1

    }

    public static class Data{ //保存地址下标
        int i;
        int j;
        Data(int i, int j){
            this.i = i;
            this.j = j;
        }
    }

    public static int findIslandNums(int[][] area){
        if(area == null){
            return 0;
        }
        int row = area.length;
        if(row == 0){
            return 0;
        }
        int col = area[0].length;
        if(col == 0){
            return 0;
        }

        int[][] v = new int[row][col]; //v数组记录该地址是否已经被访问。不初始化,默认是0

        int nums = 0;//保存岛屿个数

        for(int i = 0; i < row; i++){
            for(int j = 0; j< col; j++){ //遍历整个矩阵

                if(v[i][j] == 0){ //没有访问过
                    v[i][j] = 1; //则访问该点

                    if(area[i][j] == 1){
                        nums++;

                        Queue<Data> queue = new LinkedList<>(); //(LinkedList实现了队列接口。)队列,进行广度优先搜索
                        queue.offer(new Data(i,j)); //地址入队

                        while(!queue.isEmpty()){
                            Data ele = queue.poll(); //地址出队
                            //向上,(可以向上,没有被访问过,且为陆地)
                            if(ele.i >= 1 && v[ele.i - 1][ele.j] != 1 && area[ele.i - 1][ele.j] == 1){
                                v[ele.i - 1][ele.j] = 1;
                                queue.offer(new Data(ele.i - 1,ele.j));
                            }
                            //向右
                            if(ele.j <= col - 2 && v[ele.i][ele.j + 1] != 1 && area[ele.i][ele.j + 1] == 1){
                                v[ele.i][ele.j + 1] = 1;
                                queue.offer(new Data(ele.i, ele.j + 1));
                            }
                            //向下
                            if(ele.i <= row - 2 && v[ele.i + 1][ele.j] != 1 && area[ele.i + 1][ele.j] == 1){
                                v[ele.i + 1][ele.j] = 1;
                                queue.offer(new Data(ele.i + 1, ele.j));
                            }
                            //向左
                            if(ele.j >= 1 && v[ele.i][ele.j - 1] != 1 && area[ele.i][ele.j - 1] == 1){
                                v[ele.i][ele.j - 1] = 1;
                                queue.offer(new Data(ele.i, ele.j - 1));
                            }
                        }

                    }
                }


            }
        }

        return nums;
    }
}


具体AC代码: (因为上面传入的是int类型数组,需要转换一下)

class Solution {
    public int numIslands(char[][] grid) {
        if(grid == null){
            return 0;
        }
        int row = grid.length;
        if(row == 0){
            return 0;
        }
        int col = grid[0].length;
        if(col == 0){
            return 0;
        }

        int[][] area = new int[row][col]; 
        
         for(int i = 0; i < row; i++){
            for(int j = 0; j< col; j++){ 
                area[i][j] = grid[i][j]=='1'?1:0;
            }
           }
        
        return findIslandNums(area);
    }
    
    public class Data{ //保存地址下标
        int i;
        int j;
        Data(int i, int j){
            this.i = i;
            this.j = j;
        }
    }
    
     public int findIslandNums(int[][] area){
        if(area == null){
            return 0;
        }
        int row = area.length;
        if(row == 0){
            return 0;
        }
        int col = area[0].length;
        if(col == 0){
            return 0;
        }

        int[][] v = new int[row][col]; //v数组记录该地址是否已经被访问。不初始化,默认是0

        int nums = 0;//保存岛屿个数

        for(int i = 0; i < row; i++){
            for(int j = 0; j< col; j++){ //遍历整个矩阵

                if(v[i][j] == 0){ //没有访问过
                    v[i][j] = 1; //则访问该点

                    if(area[i][j] == 1){
                        nums++;

                        Queue<Data> queue = new LinkedList<>(); //(LinkedList实现了队列接口。)队列,进行广度优先搜索
                        queue.offer(new Data(i,j)); //地址入队

                        while(!queue.isEmpty()){
                            Data ele = queue.poll(); //地址出队
                            //向上,(可以向上,没有被访问过,且为陆地)
                            if(ele.i >= 1 && v[ele.i - 1][ele.j] != 1 && area[ele.i - 1][ele.j] == 1){
                                v[ele.i - 1][ele.j] = 1;
                                queue.offer(new Data(ele.i - 1,ele.j));
                            }
                            //向右
                            if(ele.j <= col - 2 && v[ele.i][ele.j + 1] != 1 && area[ele.i][ele.j + 1] == 1){
                                v[ele.i][ele.j + 1] = 1;
                                queue.offer(new Data(ele.i, ele.j + 1));
                            }
                            //向下
                            if(ele.i <= row - 2 && v[ele.i + 1][ele.j] != 1 && area[ele.i + 1][ele.j] == 1){
                                v[ele.i + 1][ele.j] = 1;
                                queue.offer(new Data(ele.i + 1, ele.j));
                            }
                            //向左
                            if(ele.j >= 1 && v[ele.i][ele.j - 1] != 1 && area[ele.i][ele.j - 1] == 1){
                                v[ele.i][ele.j - 1] = 1;
                                queue.offer(new Data(ele.i, ele.j - 1));
                            }
                        }

                    }
                }


            }
        }

        return nums;
    }
}

 

 

 

 

 

方法二:深度优先搜索

class Solution {
    private int[][] dir = {{-1,0},{0,1},{1,0},{0,-1}};//方向
    private int row,col;
    private char[][] grid;
    private int[][] v;   //标记是否访问
    
    public int numIslands(char[][] grid) {
        this.grid = grid;
        
        if(grid == null){
            return 0;
        }
        row = grid.length;
        if(row == 0){
            return 0;
        }
        col = grid[0].length;
        v = new int[row][col]; 
        
        int num = 0;//记录岛屿数量
        for(int i=0; i<row; i++){
            for(int j = 0; j < col; j++){
                //没有被访问过的陆地
                if(v[i][j] == 0 && grid[i][j] == '1'){
                    num++;
                   dfs(i,j);
                }
                v[i][j] = 1; //访问
            }
        }
        return num;
    }
    
    public void dfs(int i, int j){
         v[i][j] = 1; //访问
        //新下标分别为ni,nj
         int ni = 0, nj = 0;
                    
         //查看它的上下左右节点,深度优先搜索
         for(int k = 0; k < 4; k++){
             ni = i + dir[k][0];
             nj = j + dir[k][1];
             if(ni >= 0 && ni < row && nj >= 0 && nj < col && v[ni][nj]==0 && grid[ni][nj] == '1'){
                 dfs(ni,nj);
             }
         }
    }
}

 

 

 

 

ref: 题解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值