LeetCode 算法:课程表 c++

原题链接🔗:课程表
难度:中等⭐️⭐️

题目

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

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

例如,先修课程对 [0, 1] 表示:想要学习课程0,你需要先完成课程 1
请你判断是否可能完成所有课程的学习?如果可以,返回true;否则,返回false

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。

示例 2:

输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • prerequisites[i] 中的所有课程对 互不相同

拓扑排序

拓扑排序是图论中的一个概念,它对有向无环图(DAG,Directed Acyclic Graph)中的顶点进行线性排序,使得对于任何一条有向边 U -> V,顶点 U 都在顶点 V 的前面。这种排序不是唯一的。拓扑排序常用于任务调度、课程规划等场景。

以下是拓扑排序的一般步骤:

  1. 计算所有顶点的入度:入度是指有多少条边指向该顶点。对于图中的每个顶点,初始化一个计数器来记录入度。

  2. 将所有入度为0的顶点加入队列:入度为0的顶点表示没有依赖,可以首先进行排序。

  3. 处理队列中的顶点

    • 从队列中移除一个顶点,并将其加入到拓扑排序的结果列表中。
    • 遍历该顶点的所有邻接点,将每个邻接点的入度减1(因为它们的一个依赖已经完成)。
    • 如果某个邻接点的入度变为0,将其加入队列。
  4. 重复步骤3,直到队列为空。

  5. 检查环:如果拓扑排序的结果列表中的顶点数量等于原始图中的顶点数量,则图中没有环;否则,存在环,无法完成拓扑排序。

拓扑排序的算法可以用多种方式实现,包括Kahn算法和DFS(深度优先搜索)。

拓扑排序的时间复杂度通常是 O(V+E),其中 V 是顶点数,E 是边数。空间复杂度为 O(V),用于存储访问状态和排序结果。

题解

  1. 解题思路

LeetCode 上的 “课程表” 问题(问题编号207)是一个典型的图论问题,主要考察了图的深度优先搜索(DFS)和拓扑排序的应用。
以下是这个问题的解题思路:

  • 理解问题:首先,明确题目要求我们判断是否能够完成所有课程的学习。这等价于判断图中是否存在环,因为如果存在环,则表示有课程无法满足其所有先修条件。

  • 构建图:根据给定的先修关系列表 prerequisites 构建一个有向图。可以使用邻接表来表示这个图,其中每个节点代表一门课程,边表示先修关系。

  • 检测环:使用深度优先搜索(DFS)来检测图中是否存在环。在DFS过程中,使用两个集合来记录访问状态:

    • visited:记录已经访问过的节点。
    • recStack(递归栈):记录当前递归路径上的节点,用于检测环。
  • DFS逻辑

    • 对于每个未访问的节点,执行DFS。
    • 如果当前节点已经在 recStack 中,表示找到了一个环,返回 false。
    • 如果当前节点已经访问过,并且不在 recStack 中,可以跳过。
    • 将当前节点加入 visited 和 recStack。
    • 对当前节点的所有邻接节点递归执行DFS。
    • 递归返回后,将当前节点从 recStack 中移除。
  • 拓扑排序:如果所有节点都可以通过DFS访问且没有检测到环,那么图是可拓扑排序的,即可以完成所有课程的学习。

  1. c++ demo
#include <iostream>
#include <vector>
#include <queue>using namespace std;class Solution {
public:bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {vector<int> indegrees(numCourses, 0);vector<vector<int>> graph(numCourses);// 构建图并计算入度for (auto& pre : prerequisites) {graph[pre.first].push_back(pre.second);indegrees[pre.second]++;}// 拓扑排序vector<int> topsort;queue<int> q;for (int i = 0; i < numCourses; ++i) {if (indegrees[i] == 0) {q.push(i);}}while (!q.empty()) {int course = q.front();q.pop();topsort.push_back(course);for (int pre : graph[course]) {indegrees[pre]--;if (indegrees[pre] == 0) {q.push(pre);}}}// 如果所有课程都被排序了,图中没有环return topsort.size() == numCourses;}
};int main() {Solution solution;// 测试用例vector<pair<int, int>> prerequisites = { {1, 0}, {0, 1} };int numCourses = 4;bool result = solution.canFinish(numCourses, prerequisites);if (result) {cout << "It is possible to finish all courses." << endl;}else {cout << "It is not possible to finish all courses." << endl;}return 0;
}
  • 输出结果:

It is not possible to finish all courses.

  1. 代码仓库地址:canFinish

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

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

相关文章

oracle索引字段存储数据过长,导致索引失效

1&#xff1a;短位数据&#xff0c;索引生效 2&#xff1a;长位索引&#xff0c;索引不生效 此问题发现于6月中旬&#xff0c;线上问题优化。引以为戒。 解决&#xff1a; 并未解决索引不生效问题&#xff0c; 但是基于优化查询&#xff0c;是的查询保持毫秒级

第一个基于FISCOBCOS的前后端项目(发行转账)

本文旨在介绍一个简单的基于fiscobcos的前后端网站应用。Springbootjs前后端不分离。 所使用到的合约也是一个最基本的。首先您需要知道的是完整项目分为三部分&#xff0c;1是区块链平台webase搭建&#xff08;此项目使用节点前置webase-front即可&#xff09;&#xff0c;2是…

[stm32f407]GPIO配置方式

GPIO模式&#xff1a; GPIO_InitStructure.GPIO_ModeGPIO_Mode_IN;GPIO_InitStructure.GPIO_OTypeGPIO_OType_PP;//是否需要GPIO_InitStructure.GPIO_PinGPIO_Pin_11;GPIO_InitStructure.GPIO_PuPdGPIO_PuPd_UP;//上拉GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz; GPIO_Mo…

什么是防抖和节流?如何理解它们并在不同的场景条件下灵活运用?

&#x1f64b;‍♂️ 什么是防抖和节流&#xff1f; 防抖&#xff08;Debouncing&#xff09;和节流&#xff08;Throttling&#xff09;是两种常见的性能优化技术&#xff0c;常用于控制某些操作&#xff08;例如事件处理器&#xff09;的频率&#xff0c;从而减少资源消耗并…

Diffusion 公式推导 2

Diffusion 公式推导 中对 DDPM 进行了推导&#xff0c;本文接着对 DDIM 进行推导。 目录 六. 模型改进 六. 模型改进 从扩散模型的推理过程不难看出&#xff0c;DDPM 有一个致命缺点 —— 推理速度过慢&#xff0c;因为逆扩散是从 x T x_{T} xT​ 到 x 0 x_{0} x0​ 的完整过…

ubuntu 如何解压tar

在Ubuntu中解压.tar文件&#xff0c;可以使用tar命令。以下是解压.tar文件的命令&#xff1a; tar -xvf file.tar 解释&#xff1a; x 表示解压 v 表示显示过程中的详细信息&#xff08;可选&#xff09; f 表示后面跟文件名 这将在当前目录下解压file.tar文件的内容。如果…

语义分割和实例分割区别?

语义分割&#xff1a;将图像中的每个像素分配给其对应的语义类别&#xff0c;其主要针对于像素&#xff0c;或者说它是像素级别的图像分割方法。&#xff1a;语义分割的目的是为了从像素级别理解图像的内容&#xff0c;并为图像中的每个像素分配一个对象类。 实例分割&#xf…

【HarmonyOS NEXT】鸿蒙线程安全容器集collections.TypedArray

collections.TypedArray 一种线性数据结构&#xff0c;底层基于ArkTS ArrayBuffer实现。目前支持包括Int8Array、Uint8Array、Int16Array、Uint16Array、Int32Array以及Uint32Array。 文档中存在泛型的使用&#xff0c;涉及以下泛型标记符&#xff1a; TypedArray: 指上述6种…

Laravel Excel导出功能:高效实现数据导出

Laravel是一个功能丰富的PHP Web开发框架&#xff0c;它提供了许多内置功能来简化开发过程。其中&#xff0c;Laravel Excel导出功能是处理数据导出任务的强大工具。通过使用Maatwebsite的Laravel Excel包&#xff0c;开发者可以轻松地将数据集导出为Excel文件&#xff0c;这对…

软件代码漏洞风险等级

代码漏洞的风险等级通常根据漏洞的潜在影响、利用难易程度以及可能造成的损害程度来划分。不同的组织或机构可能会采用不同的标准或评分系统来评估漏洞的风险等级。以下是一些常见的代码漏洞风险等级划分标准和考虑因素: 通用漏洞评分系统(CVSS) CVSS是一种广泛使用的漏洞…

DMA方式的知识点笔记

苏泽 “弃工从研”的路上很孤独&#xff0c;于是我记下了些许笔记相伴&#xff0c;希望能够帮助到大家 目录 1. DMA基本概念 2. DMA传送过程 易错点 DMA控制器操作流程 3. DMA传送方式 这是单总线的结果 &#xff08;CPU说了算 所以不会产生于CPU的冲突&#xff09; 这…

新浪API系列:支付API打造无缝支付体验,畅享便利生活(3)

在当今数字化时代&#xff0c;支付功能已经成为各类应用和平台的必备要素之一。作为开发者&#xff0c;要构建出安全、便捷的支付解决方案&#xff0c;新浪支付API是你不可或缺的利器。新浪支付API提供了全面而强大的接口和功能&#xff0c;帮助开发者轻松实现在线支付的集成和…

软件开发面试题(C#语言,.NET框架)

1. 解释什么是委托&#xff08;Delegate&#xff09;&#xff0c;并举例说明它在C#中的用法。 委托是一种引用类型&#xff0c;它可以用于封装一个或多个方法。委托对象可以像方法一样调用&#xff0c;甚至可以用于创建事件处理程序。委托是C#中实现事件和回调函数的重要机制。…

【PyTorch][chapter 26][李宏毅深度学习][attention-1]

前言&#xff1a; attention 在自然语言处理&#xff0c;声音处理里面是一个很重要的技巧. attention 要解决的是输入的向量长度不定. 根据输入输出的不同,分为三种场景&#xff1a; 输入N个向量&#xff0c;输出N个向量,这是本章的重点 输入N个向量&#xff0c;输出向量不定 输…

人工智能与技术失业:历史教训与未来趋势

在1938年大萧条时期&#xff0c;MIT校长卡尔康普顿讨论了“技术失业”&#xff0c;即因技术进步导致的失业现象。他认为&#xff0c;尽管技术进步会对个别工人和社区产生负面影响&#xff0c;但从整体上看&#xff0c;技术进步创造了更多的就业机会。这一观点在今天依然具有重要…

施罗德数列SQL实现

在组合数学中,施罗德数用来描述从(0,0)到(n,n)的格路中,只能使用(1,0)、(0,1)、(1,1)三种移动方式,始终位于对角线下方且不越过对角线的路径数 DECLARE n INT 10 DECLARE i INT DECLARE rst INT DECLARE old INT1CREATE TABLE #rst (i INT ,rst int )INSERT INTO #rst values(…

react使用markdown进行展示

有一些文档非常长&#xff0c;但是又要挨个设置样式&#xff0c;直接用 组件库 - marked 注意文档要放在public下才能读取。但非常方便 import { marked, Renderer } from "marked".....const [html, setHtml] useState<any>("")const renderer:…

3-7 使用深度学习解决温度即示数问题

3-7 使用深度学习解决温度即示数问题 直接上代码 %matplotlib inline import matplotlib.pyplot as plt import numpy as np import torch torch.set_printoptions(edgeitems2, linewidth75)设置Jupyter Notebook在单元格中内嵌显示图像&#xff0c;导入所需库并设置PyTorch的…

代码随想三刷动态规划篇10

代码随想三刷动态规划篇10 300. 最长递增子序列题目代码 674. 最长连续递增序列题目代码 718. 最长重复子数组题目代码 1143. 最长公共子序列题目代码 1035. 不相交的线题目代码 300. 最长递增子序列 题目 链接 代码 class Solution {public int lengthOfLIS(int[] nums) {…

裸金属服务器与物理服务器之间的区别

裸金属服务器与物理服务器之间主要的区别就在于虚拟化技术、资源共享和灵活性等多种方面。 裸金属服务器主要是通过虚拟化技术将物理服务器划分成多个独立的虚拟机&#xff0c;致使每个虚拟机都具有独立的操作系统与资源&#xff1b;物理服务器则是指有着独立的服务器硬件&…