• 『牛客|每日一题』岛屿数量


    活动地址:CSDN21天学习挑战赛

    👨‍🎓作者简介:一位喜欢写作,计科专业大二菜鸟
    🏡个人主页:starry陆离

    🕒首发日期:2022年8月10日星期三

    🍁每日推荐:牛客网-面试神器
    在这里插入图片描述

    如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦

    在这里插入图片描述

    1.每日一题

    image-20220804233300588

    2.解题思路:DFS

    深度优先搜索一般用于树或者图的遍历,其他有分支的(如二维矩阵)也适用。它的原理是从初始点开始,一直沿着同一个分支遍历,直到该分支结束,然后回溯到上一级继续沿着一个分支走到底,如此往复,直到所有的节点都有被访问到。

    2.1思路分析

    整体思路就是找到一堆1就意味着找到一个岛屿,然后把他们变成0,再找下一堆1再把这堆1变成0,直到没有1为止。

    微观上的处理就是:当我们遇到矩阵的某个元素为1时,首先将其置为了0,然后查看与它相邻的上下左右四个方向,如果这四个方向任意相邻元素为1,则进入该元素,进入该元素之后我们发现又回到了刚刚的子问题,又是把这一片相邻区域的1全部置为0,因此可以用递归实现

    • step 1:首先还是要做特例检查,矩阵不能为空*且长度不能为0
    • step 2:然后找到一个1作为起始点,把与这个1相连的所有1置为0(这一步使用递归来实现)
    • step 3:找到一个1后,遍历它的四周看看还有没有1,如果有则进入更深层次的递归去找到这个1周围的1,统统把它们变为0,如此递归下去直到这片区域没有1这次递归才结束
    • step 4:然后重新找一个起始点,重复第step 3步,直到双层for循环遍历完整个矩阵再也找不到1了

    2.2核心代码

    import java.util.*;
    public class Solution {
        /**
         * 判断岛屿数量
         * @param grid char字符型二维数组 
         * @return int整型
         */
        //记录岛屿数量
        private int ans;
        //搜索的方向数组
        private int xx[]={-1,1,0,0};
        private int yy[]={0,0,-1,1};
        public int solve (char[][] grid) {
            //数组为空检查
            if(grid==null||grid.length==0){
                return 0;
            }
            //初始化岛屿数量为0
            ans=0;
            //数组的行
            int r=grid.length;
            //数组的宽
            int c=grid[0].length;
            //遍历数组矩阵找到初始点(1)
            for(int i=0;i<r;++i){
                for(int j=0;j<c;++j){
                    if(grid[i][j]=='1'){
                        //岛屿数量++
                        ans++;
                        //深搜将与这个(1)相连的所有1置为0
                        dfs(i,j,grid);
                    }
                }
            }
            return ans;
        }
        
        public void dfs(int x,int y,char [][]grid){
            //搜索的结束条件,数组越界或者此点不是1(陆地)就结束
            if(!check(x,y,grid)){
               return;
            }
            //此点被搜索过,将1置为0
            grid[x][y]=0;
            //扩展向上下左右四个方向搜索
            for(int i=0;i<4;++i){
                int dx=x+xx[i];
                int dy=y+yy[i];
                //剪枝操作:越界检查以及检查此点是不是陆地
                if(check(dx,dy,grid)){
                    dfs(dx,dy,grid);
                }
            }
        }
        //剪枝操作
        public boolean check(int x,int y,char [][]grid){
           if(x>=0&&x<grid.length&&y>=0&&y<grid[0].length&&grid[x][y]=='1'){
                return true;
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    image-20220804233328662

    3.解题思路:BFS

    广度优先搜索深度优先搜索不同,它是将与某个节点直接相连的其它所有节点依次访问一次之后,再往更深处,进入与其他节点直接相连的节点。

    bfs的时候我们常常会借助队列的先进先出,因为从某个节点出发,我们将与它直接相连的节点都加入队列,它们优先进入,则会优先弹出,在它们弹出的时候再将与它们直接相连的节点加入,由此就可以依次按层访问。

    用bfs解此题整体思路还是一样的,统计岛屿的方法可以和dfs同样遍历解决,为了去重我们还是要将所有相邻的1一起改成0,这时候同样遍历连通的广度优先搜索(bfs)可以代替dfs。

    3.1思路分析

    • step 1:首先还是要做特例检查,矩阵不能为空*且长度不能为0

    • step 2:从上到下从左到右遍历矩阵每一个位置的元素,如果该元素值为1,统计岛屿数量。

    • step 3:使用bfs将遍历矩阵遇到的1以及相邻的1全部置为0:利用一个队列来实现,每次队列把搜索到的第一个1加入队列中,然后然后向此点的上下左右四个方向扩展搜索

    • step 4:把搜索到的每一个为1的点都标记为0,目的是去重,防止重复搜索

    • step 5:直至队列为空时,说明此区域的1全被搜索完(都被置为0了)一次广搜结束,代表找到一个岛屿

    • step 6:回到solution的双重for循环重复step 2,3,4,5步直至矩阵中所有的点都被遍历

    3.2核心代码

    import java.util.*;
    
    class Node{
        int x,y;
        public Node(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
    public class Solution {
        /**
         * 判断岛屿数量
         * @param grid char字符型二维数组 
         * @return int整型
         */
        private int ans;
        private int[][]vis;
        private int[] xx={-1,1,0,0};
        private int[] yy={0,0,-1,1};
        public int solve (char[][] grid) {
            // write code here
            int n=grid.length;
            int m=grid[0].length;
            
            vis=new int[n][n];
            for(int i=0;i<n;++i){
                for(int j=0;j<m;++j){
                    if(grid[i][j]=='1'){
                        ans++;
                        grid[i][j]='0';
                        bfs(new Node(i,j),grid,n,m);
                    }
                }
            }
            return ans;
        }
        void bfs(Node node,char[][] grid,int n,int m){
            Queue<Node>q=new LinkedList<Node>();
            q.add(node);
            while(!q.isEmpty()){
                Node now=q.poll();
                if(now.x<0&&now.y<0&&now.x>=n&&now.y>=m){
                    break;
                }
                for(int t=0;t<4;++t){
                    int dx=now.x+xx[t];
                    int dy=now.y+yy[t];
                    if(dx>=0&&dy>=0&&dx<n&&dy<m&&grid[dx][dy]=='1'){
                        grid[dx][dy]='0';
                        q.add(new Node(dx,dy));
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    📚订阅专栏:『牛客刷题集锦』

    🍁每日推荐:基础算法无论在研究生面试还是求职面试都是十分重要的一环,这里推荐一款算法面试神器:牛客网-面试神器;算法题只有多刷勤刷才能保持思路与手感,大家赶紧行动起来吧(温馨提示:常见的面试问答题库也很nice哦) 在这里插入图片描述

    如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦

  • 相关阅读:
    Win11 22H2 22621.521大版本更新!
    4、Flink执行模式(流/批)详解(下)
    Linux入门之使用 ps 查看系统进程
    MySQL-InnoDB引擎-架构和事务原理
    大一作业HTML网页作业 HTML校园篮球网页作业(12个页面)
    code force 1728D - Letter Picking
    Android笔记:震动实现
    macOS - 安装使用 SQLite
    <git>如何快速上手并高效协同
    【广州华锐互动】AR远程智慧巡检在化工行业中的应用
  • 原文地址:https://blog.csdn.net/weixin_53463734/article/details/126254971