算法——图论:拓扑排序

news/2024/5/15 6:06:17

. - 力扣(LeetCode)

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

  • 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。

请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

即图中不能有环。

注意邻接表和邻接矩阵的转换。

自己的解法:拓扑排序,找出每个节点前面节点的个数,不断遍历将值为零的访问。

类似广度优先搜索,不过不完全一样,未使用队列,时间复杂度较高。

class Solution {
public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {if(prerequisites.size()==0)return true;vector<long long> pre(numCourses,0);vector<int> visited(numCourses,0);for(int i=0;i<prerequisites.size();i++){int  a=prerequisites[i][0],b=prerequisites[i][1];pre[a]++;}int maxcou=numCourses;while(maxcou--){for(int i=0;i<numCourses;i++){if(visited[i]==0&&pre[i]==0){visited[i]=1;for(int j=0;j<prerequisites.size();j++){if(prerequisites[j][1]==i)pre[prerequisites[j][0]]--;}}}}for(int i=0;i<numCourses;i++){if(visited[i]==0)return false;}        return true;}
};

注意:在while循环中判断条件为课程数量,即最多可能循环这么多次。考虑极端情况:

5->4->3->2->1,第一次到最后才找到5,第二次到最后才找到4,这样每次循环只能访问一个节点。需n次。若为1->2->3->4->5,则仅需一次即可访问全部节点。

题目中使用的是邻接矩阵,或者转换一下使用邻接表,会更方便。



官方题解:

1.深搜

class Solution {
private:vector<vector<int>> edges;vector<int> visited;bool valid = true;public:void dfs(int u) {visited[u] = 1;for (int v: edges[u]) {if (visited[v] == 0) {dfs(v);if (!valid) {return;}}else if (visited[v] == 1) {valid = false;return;}}visited[u] = 2;}bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {edges.resize(numCourses);visited.resize(numCourses);for (const auto& info: prerequisites) {edges[info[1]].push_back(info[0]);}for (int i = 0; i < numCourses && valid; ++i) {if (!visited[i]) {dfs(i);}}return valid;}
};

2.广搜

使用一个队列;将邻接矩阵转化为邻接表。

class Solution {
private:vector<vector<int>> edges;vector<int> indeg;public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {edges.resize(numCourses);indeg.resize(numCourses);for (const auto& info: prerequisites) {edges[info[1]].push_back(info[0]);++indeg[info[0]];}queue<int> q;for (int i = 0; i < numCourses; ++i) {if (indeg[i] == 0) {q.push(i);}}int visited = 0;while (!q.empty()) {++visited;int u = q.front();q.pop();for (int v: edges[u]) {--indeg[v];if (indeg[v] == 0) {q.push(v);}}}return visited == numCourses;}
};

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

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

相关文章

FPGA + 图像处理 (二) RGB转YUV色域、转灰度图及仿真

前言 具体关于色域的知识就不细说了&#xff0c;简单来讲YUV中Y通道可以理解为就是图像的灰度图&#xff0c;因此&#xff0c;将RGB转化为YUV是求彩色图的灰度直方图、进行二值化操作等的基础。 HDMI时序生成模块 这里先介绍一下仿真时用于生成HDMI时序&#xff0c;用这个时…

PS从入门到精通视频各类教程整理全集,包含素材、作业等(2)

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 初级教程素材 等文件 https://www.alipan.com/s/fC…

数据库之迁移常规操作(Postgresql篇)

一、docker安装postgresql 1. 拉取postgres docker pull postgres2. 创建容器 注&#xff1a;默认登录账户postgres, 密码123456, 对外暴露端口5432, 卷映射&#xff1a;可在物理机修改数据库配置文件 引用文章查看&#x1f440; docker run --name postgres -e POSTGRES_P…

milvus-2.3.12安装部署

使用Docker Compose安装 Milvus standalone&#xff08;即单机版&#xff09;&#xff0c;进行一个快速milvus的体验。 前提条件&#xff1a; 1.系统可以使用centos或者ubuntu 2.系统已经安装docker和docker-compose 3.milvus版本这里使用2.3.12 启动etcd、minio、milvus 由于…

Redis缓存设计与性能优化【缓存穿透、缓存击穿、缓存雪崩】

Redis缓存设计与性能优化 多级缓存架构缓存设计缓存穿透&#xff08;空数据&#xff09;造成缓存穿透的基本原因有两个&#xff1a;第一&#xff0c; 自身业务代码或者数据出现问题。第二&#xff0c; 一些恶意攻击、 爬虫等造成大量空命中。 缓存穿透问题解决方案&#xff1a;…

探索设计模式的魅力:AI大模型如何赋能C/S模式,开创服务新纪元

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 AI大模型如何赋能C/S模式&#xff0c;开创服务新纪元 数字化飞速发展的时代&#xff0c;AI大模型…