• Leecode热题100中图论章节 200. 岛屿数量 994. 腐烂的橘子 207. 课程表 208. 实现 Trie (前缀树)


    200. 岛屿数量

    200. 岛屿数量

    // 图论  dfs
    // leecode题解中nettee的岛屿问题系列通用解法
    class Solution {
        public int numIslands(char[][] grid) {
            int res = 0;   // 记录找到的岛屿数量
            for(int i = 0; i < grid.length; i++){
                for(int j = 0; j < grid[0].length; j++){
                    // 找到 1 ,res加1,同时淹没这个岛屿
                    if(grid[i][j] == '1'){
                        res++;
                        dfs(grid, i, j);
                    }
                }
            }
            return res;
        }
    
        void dfs(int[][] grid, int r, int c) {
            // 判断 base case
            if (!inArea(grid, r, c)) {
                return;
            }
            // 如果这个格子不是岛屿,直接返回
            if (grid[r][c] != 1) {
                return;
            }
            grid[r][c] = 2; // 将格子标记为「已遍历过」
            
            // 访问上、下、左、右四个相邻结点
            dfs(grid, r - 1, c);
            dfs(grid, r + 1, c);
            dfs(grid, r, c - 1);
            dfs(grid, r, c + 1);
        }
    
        //  判断坐标 (r, c) 是否在网格中
        boolean inArea(int[][] grid, int r, int c) {
            return 0 <= r && r < grid.length 
                    && 0 <= c && c < grid[0].length;
        }
    
    
    }
    
    • 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

    994. 腐烂的橘子

    994. 腐烂的橘子

    // leecode题解里nettee的解法
    // 求腐烂橘子到所有新鲜橘子的最短路径  使用 BFS
    class Solution {
        public int orangesRotting(int[][] grid) {
            Queue<int[]> queue = new LinkedList<>();
            int count = 0;    // 表示新鲜橘子的数量
    
            for(int i = 0; i < grid.length; i++){
                for(int j = 0; j < grid[0].length; j++){
                    if(grid[i][j] == 1){
                        count++;
                    }else if(grid[i][j] == 2){
                        queue.add(new int[]{i, j});
                    }
                }
            }
    
            int round = 0; // round表示腐烂的轮数
            while(count > 0 && !queue.isEmpty()){
                round++;
                int n = queue.size();
                for(int i = 0; i < n; i++){
                    int[] orange = queue.poll();
                    int r = orange[0];
                    int c = orange[1];
                    if(r - 1 >= 0 && grid[r - 1][c] == 1){
                        grid[r - 1][c] = 2;
                        count--;
                        queue.add(new int[]{r - 1, c});
                    }
                    if(r + 1 < grid.length && grid[r + 1][c] == 1){
                        grid[r + 1][c] = 2;
                        count--;
                        queue.add(new int[]{r + 1, c});
                    }
                    if(c - 1 >= 0 && grid[r][c - 1] == 1){
                        grid[r][c - 1] = 2;
                        count--;
                        queue.add(new int[]{r, c - 1});
                    }
                    if(c + 1 < grid[0].length && grid[r][c + 1] == 1){
                        grid[r][c + 1] = 2;
                        count--;
                        queue.add(new int[]{r, c + 1});
                    }                
                }
    
            }
    
            if(count > 0){
                return -1;
            }else{
                return round;
            }
        }
    }
    // 解题思路
    // 1. 一开始,我们找出所有腐烂的橘子,将它们放入队列,作为第 0 层的结点。
    // 2. 然后进行 BFS 遍历,每个结点的相邻结点可能是上、下、左、右四个方向的结点,注意判断结点位于网格边界的特殊情况。
    // 3. 由于可能存在无法被污染的橘子,我们需要记录新鲜橘子的数量。在 BFS 中,每遍历到一个橘子(污染了一个橘子),就将新鲜橘子的数量减一。如果 BFS 结束后这个数量仍未减为零,说明存在无法被污染的橘子。
    
    • 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

    207. 课程表

    207. 课程表
    在这里插入图片描述

    解题思路

    本题可约化为: 判断课程安排图是否是 有向无环图(DAG)
    通过DFS判断图中是否有环

    // leecode题解中Krahets的DFS解法
    class Solution {
       public boolean canFinish(int numCourses, int[][] prerequisites) {
           List<List<Integer>> adjacency = new ArrayList<>();
           for(int i = 0; i < numCourses; i++)
               adjacency.add(new ArrayList<>());
           int[] flags = new int[numCourses];
           for(int[] cp : prerequisites)
               adjacency.get(cp[1]).add(cp[0]);
           for(int i = 0; i < numCourses; i++)
               if(!dfs(adjacency, flags, i)) return false;
           return true;
       }
       private boolean dfs(List<List<Integer>> adjacency, int[] flags, int i) {
           if(flags[i] == 1) return false;
           if(flags[i] == -1) return true;
           flags[i] = 1;
           for(Integer j : adjacency.get(i))
               if(!dfs(adjacency, flags, j)) return false;
           flags[i] = -1;
           return true;
       }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    208. 实现 Trie (前缀树)

    b站视频讲解
    Leecode题目链接

    26叉树的建立和查询

    class Trie {
        // 26个指向下一个节点的指针,如果表示的字母在字符串中有下一个字母,就指向代表下一个字母的node节点
        // 没有 则指向为NULL
        private Trie[] children; 
        private boolean isEnd;  // 表示当前字母是否是某个字符串的结尾
    
        public Trie() {
            children = new Trie[26];
            isEnd = false;
        }
        
        public void insert(String word) {
            Trie node = this; // 初始化根节点
            for (int i = 0; i < word.length(); i++) {
                char ch = word.charAt(i);
                int index = ch - 'a';
                // 插入节点 先看看当前node是否已经有指向该字母的next指针
                // 如果没有 则新建一个节点
                if (node.children[index] == null) {
                    node.children[index] = new Trie();
                }
                // 无论是新建还是已经指向该字母的next指针
                // 当前node移动到该字母节点
                node = node.children[index];
            }
            // 如果此时的字母是插入的字符串的最后一个
            // 标记isEnd为true 表示该字母在某一个字符串里面是结束字母
            node.isEnd = true;
        }
        // 查询就是 从根节点开始能够依次查找字符串中的字母
        // 并且最后一个字母有标记结束,那么就说明之前trie树有记录同样的字符串
        public boolean search(String word) {
            Trie node = searchPrefix(word);
            return node != null && node.isEnd;
        }
        // 查询前缀和查询是否保存有同样的字符串的思路是一样的
        // 唯一的区别在于 查询的字母是不是某个字符串的结尾并不做要求
        public boolean startsWith(String prefix) {
            return searchPrefix(prefix) != null;
        }
    
        private Trie searchPrefix(String prefix) {
            Trie node = this;
            for (int i = 0; i < prefix.length(); i++) {
                char ch = prefix.charAt(i);
                int index = ch - 'a';
                if (node.children[index] == null) {
                    return null;
                }
                node = node.children[index];
            }
            return node;
        }
    }
    
    • 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
  • 相关阅读:
    FFmpeg源码:ff_h2645_extract_rbsp函数分析
    海藻酸-磷脂微囊复合水凝胶/具有细胞膜仿生温敏性水凝胶的相关内容
    java计算机毕业设计高校贫困生信息管理系统源码+mysql数据库+系统+lw文档+部署
    VLAN多变一的业务场景解答
    国家开放大学 模拟试题训练
    SQL注入:原理及示例
    Code Bloaters-代码肿胀
    DDD领域驱动设计-实体
    【数据结构】快速排序算法你会写几种?
    向毕业妥协系列之机器学习笔记:构建ML系统(一)
  • 原文地址:https://blog.csdn.net/weixin_46743838/article/details/136349564