Hot100之图论

200岛屿数量

题目

思路解析

把访问过的格子插上棋子

思想是先污染再治理,我们有一个inArea()函数,是判断是否出界了

我们先dfs()放各个方向遍历,然后我们再把这个位置标为0

我们岛屿是连着的1,所以我们遍历完后,我们要把遍历完的位置置为0,防止结果重复

代码

class Solution {
    public int numIslands(char[][] grid) {
        
int count=0;

for(int r=0;r<grid.length;r++)
{
    for(int c=0;c<grid[0].length;c++)
    {

        if(grid[r][c]=='1')
        {
            dfs(r,c,grid);
            count++;
        }
        
    }
}
return count;

    }

private void  dfs(int startindex1,int startindex2,char[][] grid)
{
    if(!inArea(grid,startindex1,startindex2))
    return ;

    if(grid[startindex1][startindex2]=='0')
    return ;

    grid[startindex1][startindex2]='0';

         dfs( startindex1- 1, startindex2,grid);
         dfs(startindex1 + 1, startindex2,grid);
         dfs( startindex1, startindex2 - 1,grid);
         dfs( startindex1, startindex2 + 1,grid);


}


boolean inArea(char[][] grid,int row,int cline)
{
    return row>=0&&row<grid.length&&cline>=0&&
    cline<grid[0].length;
}


}

994腐烂的橘子 

题目

思路解析

我们一开始要统计腐烂的橘子的位置和fresh变量统计有几个新鲜的橘子

我们每腐烂一个新鲜橘子fresh就--

要是最后腐烂完还有新鲜橘子就返回-1,表示不能全部腐烂完

解题思路:我们腐烂的橘子放四个方向腐烂

为了防止重复腐烂,我们每遍历一次旧腐烂橘子就结束,然后把新腐烂橘子加入到List<int[]>里面

然后下次从新腐烂橘子开始腐烂

例如我们for循环的遍历的tmp就是我们的旧腐烂橘子,我们开始腐烂,腐烂的同时往q收集我们的新腐烂橘子

方便我们下次4个方向遍历腐烂橘子

for循环的条件:fresh > 0 && !q.isEmpty(),新鲜橘子>0并且还有能继续遍历的腐烂橘子

while (fresh > 0 && !q.isEmpty()) {
            ans++; // 经过一分钟

            List<int[]> tmp = q;

            q = new ArrayList<>();

            for (int[] pos : tmp) { // 已经腐烂的橘子往四个方向腐烂
                for (int[] d : DIRECTIONS) { // 四方向
                    int i = pos[0] + d[0];
                    int j = pos[1] + d[1];
                    if (0 <= i && i < m && 0 <= j && j < n && grid[i][j] == 1) { // 新鲜橘子
                        fresh--;
                        grid[i][j] = 2; // 变成腐烂橘子
                        q.add(new int[]{i, j});
                    }
                }
            }

        }

代码

class Solution {
    //为了判断是否有永远不会腐烂的橘子(如示例 2),我们可以统计初始新鲜橘子的个数 fresh。
    //在 BFS 中,每有一个新鲜橘子被腐烂,就把 fresh 减一,这样最后如果发现 fresh>0,就意味着有橘子永远不会腐烂,返回 −1
    //新鲜橘子腐烂的时候我们要把1变成2
    private static final int[][] DIRECTIONS = {
  
  {-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 四方向

    public int orangesRotting(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int fresh = 0;
        List<int[]> q = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {

                if (grid[i][j] == 1) {
                    fresh++; // 统计新鲜橘子个数
                } 

                else if (grid[i][j] == 2) {
                    q.add(new int[]{i, j}); // 一开始就腐烂的橘子的下标
                }

            }
        }

        int ans = 0;
        while (fresh > 0 && !q.isEmpty()) {
            ans++; // 经过一分钟

            List<int[]> tmp = q;

            q = new ArrayList<>();

            for (int[] pos : tmp) { // 已经腐烂的橘子往四个方向腐烂
                for (int[] d : DIRECTIONS) { // 四方向
                    int i = pos[0] + d[0];
                    int j = pos[1] + d[1];
                    if (0 <= i && i < m && 0 <= j && j < n && grid[i][j] == 1) { // 新鲜橘子
                        fresh--;
                        grid[i][j] = 2; // 变成腐烂橘子
                        q.add(new int[]{i, j});
                    }
                }
            }
            
        }

        return fresh > 0 ? -1 : ans;
    }
}

207课程表

题目

思路解析

判断是否有环

例如【0,1】【1,0】

在学课程0之前要学课程1

在学课程1之前要学课程0

这就是不可能的,用图来说就是有环

访问过不代表找到了环

所以我们要有三种状态

未访问 0

正在访问 1

访问完毕 2

我们最多有numCourses个课程,所以我们遍历numCourses次

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

我们一个节点可能对应多个学习顺序

例如0->1,0->2我们学习1,2之前一个要学习0,所以我们可以顺便把1,2两个节点都dfs完

我们把节点都遍历完后我们都没找到环,就说明我们的该节点x已经访问完毕,我们标记为2

private boolean dfs(int x, List<Integer>[] g, int[] colors) {

        colors[x] = 1; // x 正在访问中

        //开始遍历该节点
        //例如0->1,0->2,我们这个节点是0节点,我们就要遍历1,2
        for (int y : g[x]) {
            if (colors[y] == 1 || colors[y] == 0 && dfs(y, g, colors)) {
                return true; // 找到了环
            }
        }

        colors[x] = 2; // x 完全访问完毕
        return false; // 没有找到环
    }

代码

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {

        List<Integer>[] g = new ArrayList[numCourses];
        Arrays.setAll(g, i -> new ArrayList<>());
        //初始化课程,也就是0->1,0->2,1->3这样子学习课程顺序初始化
        for (int[] p : prerequisites) {
            g[p[1]].add(p[0]);
        }

        //标记染色的数组
        int[] colors = new int[numCourses];
        //因为最多有numCourses个课程,所以我们最多遍历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 正在访问中

        //开始遍历该节点
        //例如0->1,0->2,我们这个节点是-节点,我们就要遍历1,2
        for (int y : g[x]) {
            if (colors[y] == 1 || colors[y] == 0 && dfs(y, g, colors)) {
                return true; // 找到了环
            }
        }

        colors[x] = 2; // x 完全访问完毕
        return false; // 没有找到环
    }
}

208实现前缀树 

题目

思路解析

26叉树结构

首先我们是26个字母,所以我们应该是26叉树

我们定义一个Node结构来实现这个26叉树

然后我们还有个end标志位,标志这个位置是否是一个一个完整的单词

class Node{
    Node[] son=new Node[26];
    boolean end;
}

例如下面

我们的apple是一个完整的单词

我们的app是一个完整的单词

但我们是一个遍历顺序,所以我们这个end标志位是必要的

前缀树的初始化

我们有个root节点,保证所有的字符串都从root开始

   private Node root;

    public Trie() {
        root=new Node();
    }
插入

相当于我们不断构建树

我们Node结构中有一个Node数组 Node[] son=new Node[26]

我们用0,1,2,3表示a,b,c,d......

然后我们移动到遍历的字符的位置

最后单词遍历完毕我们有个end标志位,标志结束

public void insert(String word) {

    Node cur = root; // 从根节点开始

    for (char c : word.toCharArray()) {
        c -= 'a'; // 将字符转换为索引('a' -> 0, 'b' -> 1, ..., 'z' -> 25)
        if (cur.son[c] == null) { // 如果当前字符对应的子节点不存在
            cur.son[c] = new Node(); // 创建新节点
        }
        cur = cur.son[c]; // 移动到子节点
    }

    cur.end = true; // 标记单词的结尾

    }
find找单词

也就是从root节点开始找单词

private int find(String word) {
    Node cur = root; // 从根节点开始
    for (char c : word.toCharArray()) {
        c -= 'a'; // 将字符转换为索引
        if (cur.son[c] == null) { // 如果当前字符对应的子节点不存在
            return 0; // 返回 0,表示未找到
        }
        cur = cur.son[c]; // 移动到子节点
    }
    return cur.end ? 2 : 1; // 如果当前节点是单词结尾,返回 2;否则返回 1
}
search和startsWith

search:如果等于2说明前缀树中有这个单词

find:如果等于1或2说明我们前缀树中有这个单词前缀

public boolean search(String word) {
        return find(word)==2;//检查是否是完整单词
    }

    public boolean startsWith(String prefix) {
        return find(prefix) != 0;
    }

代码

class Node{
    Node[] son=new Node[26];
    boolean end;
}

class Trie {

    private Node root;

    public Trie() {
        root=new Node();
    }
    
    public void insert(String word) {

    Node cur = root; // 从根节点开始

    for (char c : word.toCharArray()) {
        c -= 'a'; // 将字符转换为索引('a' -> 0, 'b' -> 1, ..., 'z' -> 25)
        if (cur.son[c] == null) { // 如果当前字符对应的子节点不存在
            cur.son[c] = new Node(); // 创建新节点
        }
        cur = cur.son[c]; // 移动到子节点
    }

    cur.end = true; // 标记单词的结尾

    }
    
    private int find(String word) {
    Node cur = root; // 从根节点开始
    for (char c : word.toCharArray()) {
        c -= 'a'; // 将字符转换为索引
        if (cur.son[c] == null) { // 如果当前字符对应的子节点不存在
            return 0; // 返回 0,表示未找到
        }
        cur = cur.son[c]; // 移动到子节点
    }
    return cur.end ? 2 : 1; // 如果当前节点是单词结尾,返回 2;否则返回 1
}
    
    public boolean search(String word) {
        return find(word)==2;//检查是否是完整单词
    }

    public boolean startsWith(String prefix) {
        return find(prefix) != 0;
    }


}

/**
 * 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);
 */

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/963237.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)

目录 1 -> 生命周期 1.1 -> 应用生命周期 1.2 -> 页面生命周期 2 -> 资源限定与访问 2.1 -> 资源限定词 2.2 -> 资源限定词的命名要求 2.3 -> 限定词与设备状态的匹配规则 2.4 -> 引用JS模块内resources资源 3 -> 多语言支持 3.1 -> 定…

Python从零构建macOS状态栏应用(仿ollama)并集成AI同款流式聊天 API 服务(含打包为独立应用)

在本教程中,我们将一步步构建一个 macOS 状态栏应用程序,并集成一个 Flask 服务器,提供流式响应的 API 服务。 如果你手中正好持有一台 MacBook Pro,又怀揣着搭建 AI 聊天服务的想法,却不知从何处迈出第一步,那么这篇文章绝对是你的及时雨。 最终,我们将实现以下功能: …

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.4 索引优化:避免意外复制的高效技巧

2.4 索引优化&#xff1a;避免意外复制的高效技巧 目录/提纲 #mermaid-svg-hmMAIqF8kFh46fbH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hmMAIqF8kFh46fbH .error-icon{fill:#552222;}#mermaid-svg-hmMAIqF8kF…

【C语言进阶(五)】指针进阶详解(下)

指针详解-下 1. 前言2. 函数指针数组2.1 函数指针数组的用途 3. 指向函数指针数组的指针3.1 回调函数 4. 库函数中qsort分析4.1 为什么这个函数需要我们自己实现?4.2 库函数qsort的使用 5. qsort函数的模拟实现5.1 大框架的实现5.2 比较函数的实现5.3 对于交换函数的思考5.4 交…

18.Word:数据库培训课程❗【34】

目录 题目 NO1.2.3.4 NO5设置文档内容的格式与样式 NO6 NO7 NO8.9 NO10.11标签邮件合并 题目 NO1.2.3.4 FnF12&#xff1a;打开"Word素材.docx”文件,将其另存为"Word.docx”在考生文件夹下之后到任务9的所有操作均基于此文件&#xff1a;"Word.docx”…

99.24 金融难点通俗解释:MLF(中期借贷便利)vs LPR(贷款市场报价利率)

目录 0. 承前1. 什么是MLF&#xff1f;1.1 专业解释1.2 通俗解释1.3 MLF的三个关键点&#xff1a; 2. 什么是LPR&#xff1f;2.1 专业解释2.2 通俗解释2.3 LPR的三个关键点&#xff1a; 3. MLF和LPR的关系4. 传导机制4.1 第一步&#xff1a;央行调整MLF4.2 第二步&#xff1a;银…

五. Redis 配置内容(详细配置说明)

五. Redis 配置内容(详细配置说明) 文章目录 五. Redis 配置内容(详细配置说明)1. Units 单位配置2. INCLUDES (包含)配置3. NETWORK (网络)配置3.1 bind(配置访问内容)3.2 protected-mode (保护模式)3.3 port(端口)配置3.4 timeout(客户端超时时间)配置3.5 tcp-keepalive()配置…

用 HTML、CSS 和 JavaScript 实现抽奖转盘效果

顺序抽奖 前言 这段代码实现了一个简单的抽奖转盘效果。页面上有一个九宫格布局的抽奖区域&#xff0c;周围八个格子分别放置了不同的奖品名称&#xff0c;中间是一个 “开始抽奖” 的按钮。点击按钮后&#xff0c;抽奖区域的格子会快速滚动&#xff0c;颜色不断变化&#xf…

【Linux系统】计算机世界的基石:冯诺依曼架构与操作系统设计

文章目录 一.冯诺依曼体系结构1.1 为什么体系结构中要存在内存&#xff1f;1.2 冯诺依曼瓶颈 二.操作系统2.1 设计目的2.2 系统调用与库函数 一.冯诺依曼体系结构 冯诺依曼体系结构&#xff08;Von Neumann Architecture&#xff09;是计算机的基本设计理念之一&#xff0c;由…

说说Redis的内存淘汰策略?

大家好&#xff0c;我是锋哥。今天分享关于【说说Redis的内存淘汰策略?】面试题。希望对大家有帮助&#xff1b; 说说Redis的内存淘汰策略? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 提供了多种内存淘汰策略&#xff0c;用于在内存达到限制时决定如何…

【python】python基于机器学习与数据分析的手机特性关联与分类预测(源码+数据集)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 python基于机器学习与数据分析的手机特性关联与分类…

Flutter_学习记录_Tab的简单Demo~真的很简单

1. Tab的简单使用了解 要实现tab(选项卡或者标签视图)需要用到三个组件&#xff1a; TabBarTabBarViewTabController 这一块&#xff0c;我也不知道怎么整理了&#xff0c;直接提供代码吧&#xff1a; import package:flutter/material.dart;void main() {runApp(MyApp());…

JavaScript中的数组方法总结+详解

在JS中,数组方法是非常重要且常用的方法.在此整理总结一番. 1. javaScript常用数组方法 2.方法详解 1.push(); 功能: 在数组最后一位添加一个或多个元素,并返回新数组的长度,改变原数组.(添加多个元素用逗号隔开) var arr [1, 2, "c"];var rel arr.push(&q…

蓝桥杯之c++入门(二)【输入输出(上)】

目录 前言1&#xff0e;getchar和 putchar1.1 getchar()1.2 putchar() 2&#xff0e;scanf和 printf2.1 printf2.1.1基本用法2.1.2占位符2.1.3格式化输出2.1.3.1 限定宽度2.1.3.2 限定小数位数 2.2 scanf2.2.1基本用法2.2.2 占位符2.2.3 scanf的返回值 2.3练习练习1&#xff1a…

[EAI-028] Diffusion-VLA,能够进行多模态推理和机器人动作预测的VLA模型

Paper Card 论文标题&#xff1a;Diffusion-VLA: Scaling Robot Foundation Models via Unified Diffusion and Autoregression 论文作者&#xff1a;Junjie Wen, Minjie Zhu, Yichen Zhu, Zhibin Tang, Jinming Li, Zhongyi Zhou, Chengmeng Li, Xiaoyu Liu, Yaxin Peng, Chao…

3.5.5 基于横盘结构的分析体系——缠论(走势类型)

走势 缠论中走势的定义如下&#xff1a; 包含一个中枢的走势——盘整 包含两个或多个中枢的走势——趋势 方向 趋势&#xff08;两中枢或多中枢&#xff09; 盘整&#xff08;一中枢&#xff09; 上涨 下跌 表1-8 盘整和趋势类型的走势理论图。 趋势和中枢 …

使用PyQt5绘制带有刻度的温度计控件

前言&#xff1a;进入学习Python开发上位机界面的第二阶段&#xff0c;学习如何开发自定义控件&#xff0c;从常用的控件入手学习&#xff0c;本期主要学习如何使用PyQt5绘制带有刻度的温度计控件。 1. 先找到一篇参考文章 参考文章&#xff1a;Qt编写自定义控件5-柱状温度计…

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析

赛博算卦之周易六十四卦JAVA实现:六幺算尽天下事,梅花化解天下苦。

佬们过年好呀~新年第一篇博客让我们来场赛博算命吧&#xff01; 更多文章&#xff1a;个人主页 系列文章&#xff1a;JAVA专栏 欢迎各位大佬来访哦~互三必回&#xff01;&#xff01;&#xff01; 文章目录 #一、文化背景概述1.文化起源2.起卦步骤 #二、卦象解读#三、just do i…

「AI学习笔记」深度学习的起源与发展:从神经网络到大数据(二)

深度学习&#xff08;DL&#xff09;是现代人工智能&#xff08;AI&#xff09;的核心之一&#xff0c;但它并不是一夜之间出现的技术。从最初的理论提出到如今的广泛应用&#xff0c;深度学习经历了几乎一个世纪的不断探索与发展。今天&#xff0c;我们一起回顾深度学习的历史…