当前位置: 首页 > article >正文

力扣-Hot100-图论【算法学习day.38】

前言

###我做这类文档一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!!


习题

1.岛屿数量

题目链接:200. 岛屿数量 - 力扣(LeetCode)

题面:

分析:定义一个递归函数,用于将从某一点开始的四周相邻的1全部标记,然后我们遍历这个二阶数组,如果grid[i][j]==1&&flag[i][j]==0(flag表示标记该点是否属于其他岛屿),就将该点传入递归函数,将同属于该岛屿的所有点打上标记,ans++,最后返回ans即可

代码:

class Solution {
    int[][] flag;
    char[][] grid;
    int n;
    int m;
    int ans = 0;
    public int numIslands(char[][] grid) {
        n = grid.length;
        m = grid[0].length;
        flag = new int[n][m];
        this.grid = grid;
        for(int i = 0;i<n;i++){
            for(int j = 0;j<m;j++){
                if(flag[i][j]==0&&grid[i][j]=='1'){
                ans++;
                recursion(i,j);
                }
            }
        }
        return ans;
    }

    public void recursion(int i,int j){
        if(grid[i][j]!='1'||flag[i][j]==1)return;
        flag[i][j] = 1;
        //上
        if(i-1>=0&&flag[i-1][j]==0)recursion(i-1,j);
        //下
        if(i+1<n&&flag[i+1][j]==0)recursion(i+1,j);
        //左
        if(j-1>=0&&flag[i][j-1]==0)recursion(i,j-1);
        //右
        if(j+1<m&&flag[i][j+1]==0)recursion(i,j+1);
    }
}

2.腐烂的橘子

题目链接:994. 腐烂的橘子 - 力扣(LeetCode)

题面:

分析:模拟题,我们可以先遍历二维数组,定义两个队列,来存放下一分钟开始向四周腐烂的橘子的行纵坐标, 在额外定义一个遍历来表示新鲜橘子的剩余数量,然后每分钟开始时,我们从队列中取烂橘子,定义一个函数,用来表示一个橘子向四周腐烂的过程,如果将好橘子变成了坏橘子,就将这个新的坏橘子存入队列,并让新鲜橘子减一,当队列中不存在坏橘子时,循环结束,如果仍有好橘子存在,就返回-1,否则返回时间记录变量ans,详细看代码:

代码:

class Solution {
    public int orangesRotting(int[][] grid) {
        Queue<Integer> qi = new LinkedList<>();
        Queue<Integer> qj = new LinkedList<>();
        int ans = 0;
        int n = grid.length;
        int m = grid[0].length;
        int freshOrange = 0;
        for(int i = 0;i<n;i++){
            for(int j = 0;j<m;j++){
                if(grid[i][j]==2){
                    qi.offer(i);
                    qj.offer(j);
                }
                else if(grid[i][j]==1){
                    freshOrange++;
                }
            }
        }
        if(freshOrange==0)return 0;
        // System.out.println(freshOrange);
        // System.out.println(qi.size());
        while(!qi.isEmpty()){
            ans++;
        // System.out.println(freshOrange+" "+qi.size());
            int flag = qi.size();
            for(int k = 0;k<flag;k++){
                int i = qi.poll();
                int j = qj.poll();
                //上
                if(i-1>=0&&grid[i-1][j]==1){
                    grid[i-1][j]=2;
                    qi.offer(i-1);
                    qj.offer(j);
                    freshOrange--;
                }
                //下
                if(i+1<n&&grid[i+1][j]==1){
                    grid[i+1][j]=2;
                    qi.offer(i+1);
                    qj.offer(j);
                    freshOrange--;
                }
                //左
                if(j-1>=0&&grid[i][j-1]==1){
                    grid[i][j-1]=2;
                    qi.offer(i);
                    qj.offer(j-1);
                    freshOrange--;
                }
                //右
                if(j+1<m&&grid[i][j+1]==1){
                    grid[i][j+1]=2;
                    qi.offer(i);
                    qj.offer(j+1);
                    freshOrange--;
                }
            }      
        }
        if(freshOrange>0)return -1;
        return ans-1;

    }
}

3.课程表

题目链接:207. 课程表 - 力扣(LeetCode)

题面:

分析:主要是看有没有成环

代码:

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<Integer>[] g = new ArrayList[numCourses];
        Arrays.setAll(g, i -> new ArrayList<>());
        for (int[] p : prerequisites) {
            g[p[1]].add(p[0]);
        }

        int[] colors = new int[numCourses];
        for (int i = 0; i < numCourses; i++) {
            if (colors[i] == 0 && dfs(i, g, colors)) {
                return false; // 有环
            }
        }
        return true; // 没有环
    }

    private boolean dfs(int x, List<Integer>[] g, int[] colors) {
        colors[x] = 1; // x 正在访问中
        for (int y : g[x]) {
            if (colors[y] == 1 || colors[y] == 0 && dfs(y, g, colors)) {
                return true; // 找到了环
            }
        }
        colors[x] = 2; // x 完全访问完毕
        return false; // 没有找到环
    }
}

4.实现前缀Trie

题目链接:208. 实现 Trie (前缀树) - 力扣(LeetCode)

题面:

分析:

        1.暴力做法就是把字符串存数组里,判断字符串是否存在就是遍历数组,判断是否以某一字符串作为开头,就是使用startWith函数

        2.我们可以定义一个内部类Node,表示节点,他有两个属性,分别是子节点数组和是否是end(为某个单词的最后一个字母),当添加一个单词时,我们从root出发,遍历这个单词,如果某个子节点不存在,就创建这个子节点,查某个单词时,就看遍历时是不是都存在以及是否最后一个节点的end值为true,而查前缀就只需看是否都存在,具体请看下图

代码:

class Node{
   Node[] son = new Node[26];
   boolean end;
}
class Trie {
    Node root;
    public Trie() {
      root = new Node();
    }
    
    public void insert(String word) {
       char[] chars = word.toCharArray();
       int n = chars.length;
       Node node = root;
       for(int i = 0;i<n;i++){
            int flag = chars[i]-'a';
            if(node.son[flag]==null){
               node.son[flag] = new Node(); 
            }
            node = node.son[flag];
       }
       node.end = true;
    }
    
    public boolean search(String word) {
       char[] chars = word.toCharArray();
       int n = chars.length;
       Node node = root;
       for(int i = 0;i<n;i++){
            int flag = chars[i]-'a';
            if(node.son[flag]==null){
              return false;
            }
            node = node.son[flag];
       }
       if(node.end)return true;
       return false;
    }
    
    public boolean startsWith(String prefix) {
       char[] chars = prefix.toCharArray();
       int n = chars.length;
       Node node = root;
       for(int i = 0;i<n;i++){
            int flag = chars[i]-'a';
            if(node.son[flag]==null){
              return false;
            }
            node = node.son[flag];
       }
       return true;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */

后言

上面是力扣Hot100的图论专题,下一篇是其他专题的习题,希望有所帮助,一同进步,共勉!

 


http://www.kler.cn/a/407074.html

相关文章:

  • Wekan看板安装部署与使用介绍
  • 海洋通信船舶组网工业4G路由器应用
  • mysql的优化
  • 14 go语言(golang) - 并发编程goroutine和channel
  • 移动充储机器人“小奥”的多场景应用(上)
  • 网络安全-企业环境渗透2-wordpress任意文件读FFmpeg任意文件读
  • 基于Java Springboot高校教务管理系统
  • 【编程题目】列表、元组及集合
  • 【话题】Bug 故事:跨时区的时间转换错误
  • python运动统计 2024年9月python二级真题 青少年编程电子学会编程等级考试python二级真题解析
  • MySQL监控工具与性能分析方法:深入剖析与实践
  • MATLAB中Simulink的基础知识
  • 湖北某高校联合开源网安打造协同育人新范式,推动智能网联汽车行业可持续发展
  • _FYAW智能显示控制仪表的简单使用_串口通信
  • Java中的类加载器
  • 【Linux课程学习】:命令行参数,环境变量
  • 【Python系列】 Base64 编码:使用`base64`模块
  • 爬虫实战:从HTTP请求获取数据解析社区
  • Vscode进行Java开发环境搭建
  • win10 禁止更新
  • 【大语言模型】ACL2024论文-17 VIDEO-CSR:面向视觉-语言模型的复杂视频摘要创建
  • React第七节 组件三大属性之 refs 的用法注意事项
  • java-排序算法汇总
  • 归并排序与逆序对问题(C语言版)
  • Spark RDD Checkpoint 数据的保存机制
  • VSCode打开c#项目报错:DotnetAcquisitionTimeoutError