LeetCode207.课程表

 4e2eeb22eab546eba67738744f676cca.png

 看完题我就想,这不就是进程里面的死锁问题嘛,进程1等进程2释放锁,进程2等进程3释放锁,进程3等进程1释放锁,这就造成了死锁。或者是spring中的循环依赖问题,BeanA的初始化需要初始化一个BeanB,BeanB的初始化需要初始化BeanA就出现了循环依赖。

我记得的死锁的判断是用简化图的方式,先找出能最先完成的进程,然后把这个点消掉,再找在等待这个进程的进程里面最容易完成看看能不能消掉,消到最后不能消,如果有环就会死锁  

63f88049081143038020e9a7f2253725.jpeg

 而spring中解决循环依赖问题用的是三级缓存就与这道题无关了

b9fe9fb7b62f4484aae4c0bc998b6485.png

如果用简化图就太麻烦了,我就想用hashmap,我把prerequisites数组里的数据以k-v的形式存在HashMap里面,然后用get方法去拿到请求链中的节点放到一个set里面,如果这个节点早就在set中那么就出现了循环,于是几分钟就写出了下面的代码:

class Solution {public boolean canFinish(int numCourses, int[][] prerequisites) {int n = prerequisites.length;Map<Integer, Integer> map = new HashMap<>();for(int i=0;i<n;i++){map.put(prerequisites[i][0],prerequisites[i][1]);}for(int i =0;i<n;i++){Integer key = prerequisites[i][0];Set<Integer> set = new HashSet<>();set.add(key);while(map.containsKey(key)){if(set.contains(map.get(key))){return false;}else{key = map.get(key);set.add(key);}}}return true;}
}

然后出错了,

bef884a35d3a4761826155c974861031.png

因为我忽略了一门课的选修课有多门,hashmap如果key相同后面的value会覆盖前面的value。然后自己想了很久写没想出来然后就看题解了。

class Solution {List<List<Integer>> edges;int visit[];boolean valid = true;public boolean canFinish(int numCourses, int[][] prerequisites) {edges = new ArrayList<List<Integer>>();for(int i=0;i<numCourses;i++){edges.add(new ArrayList<Integer>());}visit = new int[numCourses];for(int[] info : prerequisites){edges.get(info[0]).add(info[1]);}for(int i=0;i<numCourses && valid;i++){if(visit[i] == 0){dfs(i);}}return valid;}public void dfs(int u){visit[u] = 1;for(int v : edges.get(u)){if(visit[v] == 0){dfs(v);if(valid == false){return;}}else if(visit[v] == 1){valid = false;return;} }visit[u] = 2;}
}

 题解用的是深度优先搜索。如果我们把课程作为他的先修课的先行节点,我们可以得到一个图

81c899483ee44e25a73b23ee8a5cf59e.png

 比如这个图就是要学A就必须先学F,E,C,要学F必须先学E,G,而E和G不需要先学其他课程,所以可以先把E和G学了然后F也可以学了....

题解用的是深度优先遍历可以结合下面的图更方便理解

0a0cf70e10a14441b50b3637398133ee.png

03538ffa22fa407fbac16d93f727d9ee.png ec4035676a0743b8a8fa22ea397404d3.png

它用List<List<Integer>> edges的结构构成一个图,外层的List放的是从0到numCourse-1门课程,内层放的是这门课程的先修课程。然后用一个int [] visited数组表是节点的状态,visit[i]=0表示还没有搜索i节点(上图中没有颜色的节点),visit[i]=1表示正在搜索这个节点(上图中黄色的节点),已经搜索过的节点(上图中绿色的节点),然后boolean valid是最后返回的结果,初始化为true,它只能被改成false不能被改成true,所以当有节点出现了死循环就把valid改成false,最后返回的valid就是false不可能是true。

然后先看dfs()方法:

public void dfs(int u){visit[u] = 1;for(int v : edges.get(u)){if(visit[v] == 0){dfs(v);if(valid == false){return;}}else if(visit[v] == 1){valid = false;return;} }visit[u] = 2;}

 课程u进入dfs后先把visit[u]从0改成1,表示正在访问u节点,然后通过edges.get(u),拿到u课程的所有先修课程vv,然后对这些先修课程v进行判断,

如果先修课程v的visit[v]=0,表示还没有搜索这个课程,递归调用dfs对它进行搜索;

如果visit[v]=1说明这个课程节点在之前已经开始搜索了但是还没有完成搜索,而又重新回到了这个节点,说明出现了环,那么就把valid改成false直接返回;

所以在前面visit[v]=0的情况下,dfs完了,如果valid变成了false就可以直接返回。

所以当visit[v]=2的时候,表示可以搜索到,不用做任何操作,直接进入判断下一个先行课;

当u的所有先修课程都判断完了并且没有出现valid改成fasle返回的情况,那么表明u的所有先修课都可以搜索到,那么u也可以搜索到了,把visit[u]改成2。

然后再看主方法:

 public boolean canFinish(int numCourses, int[][] prerequisites) {edges = new ArrayList<List<Integer>>();for(int i=0;i<numCourses;i++){edges.add(new ArrayList<Integer>());}visit = new int[numCourses];for(int[] info : prerequisites){edges.get(info[0]).add(info[1]);}for(int i=0;i<numCourses && valid;i++){if(visit[i] == 0){dfs(i);}}return valid;}

 先对edges创建一个外层的List,然后再用for循环在这个外层List的每个节点上创建一个Lsit,创建一个visit数组,这都是初始化操作。然后再看下面这个for,他是edges.get(info[0])拿到了外层节点,然后再add(info[1])把先修课挂在了这个节点上,

题解用的是edges.get(info[1]).add(info[0]),我改成了edges.get(info[0]).add(info[1]),因为我觉得这样更好理解,两种都可以跑通。题解是按照上面的图来的,以课程作为他的先修课的先行节点,题解它其实是一个反向图,我们的目的是要判断有没有循环依赖,也就是有没有环,而有没有环与方向的正反无关。

然后只要把所有课程都dfs一遍就可以,for循环里面可以加上&&valid条件,这样一旦fasle后面就不用判断了,效率可以提高一点。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Instant Web API .Net Core Crack

Instant Web API .Net Core 是立即构建即时数据库 Web API&#xff0c;无需编码。在几分钟内生成您的 Web API&#xff0c;以更快地构建应用程序。使用 VS 2022 和 Entity Framework Core 为任何 MS SQL 数据库生成 Web API。 新功能 - 使用 Visual Studio 2022 为 PostgreSQL …

自动化测试学习指南

软件自动化测试的学习步骤 大概步骤如下&#xff1a; 1. 做好手工测试&#xff08;了解各种测试的知识&#xff09;-> 2. 学习编程语言-> 3. 学习Web基础&#xff08;HTML,HTTP,CSS,DOM,Javascript&#xff09;或者 学习Winform -> 4. 学习自动化测试工具 ->5.…

字符串和内存函数(2)

文章目录 2.13 memcpy2.14 memmove2.15 memcmp2.16 memset 2.13 memcpy void* memcpy(void* destination, const void* source, size_t num); 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。这个函数在遇到 ‘\0’ 的时候并不会停下来。如果so…

AQS和ReentrantLock还能这样理解?

1.公平锁和非公平锁 1.1含义 公平锁:在竞争环境下&#xff0c;先到临界区的线程比后到的线程一定更快地获取得到锁。非公平锁:先到临界区的线程未必比后到的线程更快地获取得到锁。 1.2如何自我实现 公平锁实现&#xff1a;可以把竞争的线程放在一个先进先出的队列上。只要…

你了解Postman 变量吗?

变量是在Postman工具中使用的一种特殊功能&#xff0c;用于存储和管理动态数据。它们可以用于在请求的不同部分、环境或集合之间共享和重复使用值。 Postman变量有以下几种类型&#xff1a; 1、环境变量&#xff08;Environment Variables&#xff09;: 环境变量是在Postman…

2023.11.22 数据仓库2-维度建模

目录 1.数仓建设方案 2.数仓结构图,项目架构图 2.1项目架构图 2.2数仓结构图 3.建模设计 4.维度建模 什么是事实表: 什么是维度表: 数据发展模式y以及对应的模型 5.数仓建设规范 数据库划分规范 表命名规范 表字段类型规范 1.数仓建设方案 ODS: 源数据层(临时存储层) 贴…

防爆智能安全帽、防爆手持终端,防爆智能矿灯守护安全,在煤矿安全生产远程可视化监管中的应用

煤矿安全新守护&#xff1a;如何通过防爆智能装备实现远程可视化监管 煤矿是国民经济的重要支柱产业&#xff0c;但长期以来&#xff0c;安全生产事故的频发一直是困扰煤矿行业发展的严峻问题。安全生产事故不仅危及矿工的生命安全&#xff0c;也对企业和地方经济造成了重大的…

csdn最新最全pytest系列——pytest-xdist插件之多进程运行测试用例|| pytest-parallel插件之多线程运行测试用例

pytest之多进程运行测试用例(pytest-xdist) 前言 平常我们功能测试用例非常多时&#xff0c;比如有1千条用例&#xff0c;假设每个用例执行需要1分钟&#xff0c;如果单个测试人员执行需要1000分钟才能跑完当项目非常紧急时&#xff0c;会需要协调多个测试资源来把任务分成两部…

HPC 集群计算类型的注意事项

HPC 集群计算类型的注意事项 HPC 工作负载在 CPU &#xff0c;内存&#xff0c;网络和存储资源需求方面有不同的要求。 您可以从以下内容开始: 核心计数每个核心的内存网络带宽和等待时间处理器时钟速度 目标是选取返回最佳性价比的计算配置。 HPC 工作负载可以与单个核心作…

Centos8上部署MySQL主从备份

虚拟机环境如下&#xff1a; Node1192.168.1.110Centos8 Node2192.168.1.111Centos8 1.在Node1和Node2上安装数据库&#xff1b; yum install -y mysql* 2.关闭防火墙服务&#xff0c;关闭开启自启&#xff1b; systemctl stop firewalld systemctl disable firewall…

2022年06月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 角色初始位置如图所示,下面哪个选项能让角色移到舞台的左下角? A: B: C: D: </

VirtualBox配置共享文件夹,如果你一直安装增强功能失败,又没有尝试过改内核版本。。。

1 背景 想设置电脑本地和virtualbox虚拟机之间的共享文件夹&#xff0c;这样在电脑本地对共享文件的修改&#xff0c;就可以在虚拟机中被感知。 如果想配置共享文件夹&#xff0c;前提是必须安装virtualbox的增强功能。 我的虚拟机是7.0.10版本 安装的centOS8.5 可以看我之前的…

内网穿透隐秘隧道搭建

别低头&#xff0c;皇冠会掉&#xff1b;别流泪&#xff0c;贱人会笑。 本文首发于先知社区&#xff0c;原创作者即是本人 0x00 前言 构建内网隐蔽通道&#xff0c;从而突破各种安全策略限制&#xff0c;实现对目标服务器的完美控制。 当我们从外网成功获得攻击点的时候&…

计算机基础知识56

choices参数的使用 # 应用场景&#xff1a; 学历&#xff1a;小学、初中、高中、本科、硕士、博士、1 2 3 4 5 6 客户来源: 微信渠道、广告、介绍、QQ、等等 性别&#xff1a;男、女、未知 # 对于以上可能被我们列举完的字段我们一般都是选择使用…

HubSpot驱动业务增长:客户拓展的完美引擎!

随着数字化时代的来临&#xff0c;企业面临着前所未有的挑战&#xff0c;尤其在拓展客户方面&#xff0c;传统的方法已经难以适应新的市场环境。在这个背景下&#xff0c;数字化时代的客户拓展变得更为复杂&#xff0c;企业需要更智能、更综合的解决方案来脱颖而出。 HubSpot作…

虚拟机VMware+Ubuntu系统的自定义安装教程(详细图文教程)

VMware可以帮助你在一个操作系统的环境下安装和运行另一个操作系统&#xff0c;从而提高IT效率&#xff0c;降低运维成本&#xff0c;加快工作负载部署速度&#xff0c;提高应用性能&#xff0c;提高服务器可用性&#xff0c;消除服务器数量剧增情况和复杂性。 目录 一、VMwar…

virtualbox 扩展磁盘后在win10 虚拟机看不到新扩展的空间

造成标题中问题的原因是&#xff0c;扩展的是win10.vdi 的空间&#xff0c;虚拟机使用使用的下边那个以uuid命名的空间&#xff0c;将这个磁盘的虚拟分配空间也调整到150G . 然后在win10的磁盘管理里就可以看到新加的空间了。之后再点相应的盘进行扩展卷操作即可。

SUDS: Scalable Urban Dynamic Scenes

SUDS: Scalable Urban Dynamic Scenes&#xff1a;可扩展的城市动态场景 创新点 1.将场景分解为三个单独的哈希表数据结构&#xff0c;以高效地编码静态、动态和远场辐射场 2.利用无标签的目标信号&#xff0c;包括RGB图像、稀疏LiDAR、现成的自监督2D描述符&#xff0c;以及…

【django+vue】连接数据库、登录功能

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【djangovue专栏】 1.【djangovue】项目搭建、解决跨域访问 【djangovue】连接数据库、登录功能 django连接数据库1.安装MySQL驱动程序2.创建数据库3.配置settings.py文件4.创建表5.添加数据 登录功能1.django实现…

编译QT Mysql库并集成使用

安装MSVC编译器与Windows 10 SDK 打开Visual Studio Installer&#xff0c;如果已经安装过内容了可能是如下页面&#xff0c;点击修改&#xff08;头一回打开的话不需要这一步&#xff09;&#xff1a; 然后在工作负荷中勾选使用C的桌面开发&#xff0c;它会帮我们勾选好一些…