leetcode.207:课程表

这是一个关于LeetCode 207问题的解析,主要讨论如何使用图的深度优先搜索(DFS)和广度优先搜索(BFS)判断能否完成所有课程的学习。文章介绍了图的概念、邻接表和邻接矩阵的表示,以及如何利用DFS和BFS避免图中循环,并通过访问状态判断是否存在环。同时,提供了两种搜索策略的具体实现思路。
摘要由CSDN通过智能技术生成

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

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]

给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?

示例 1:

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

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

提示:

输入的先决条件是由 边缘列表 表示的图形,而不是 邻接矩阵 。详情请参见图的表示法。
你可以假定输入的先决条件中没有重复的边。
1 <= numCourses <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
图的深度优先搜索,或者广度优先搜索。
这道题是第一次做图相关的问题,很多东西都不熟悉,包括邻接表的构建,递归的终止条件,以及图的循环,这里写几个自己当时没有想到的东西。
1. 图的定义,首先与链表或者二叉树不同的是,图没有头结点,如需要遍历图,需要知道图所有的节点,因此图的题目一般是寻找路径,判断是否有环,最短路径之类的问题,不存在遍历图对每个节点做某种操作(个人理解);
2. 邻接表,邻接表是一个二维的链表,实际操作中常常用vector来模拟,它的第一维是图中所有节点的集合,每个节点其后的链表是与这个节点相邻的节点
3. 邻接矩阵,是一个二维的矩阵,与邻接表不同的是,邻接矩阵需要显式的表示所有节点之间两两关系,因此在稀疏图中使用邻接矩阵会有大量的0导致空间浪费
4. 可以通过visit数组的三种状态来判断是否有环,正处于dfs过程中是一种状态,没被访问过是一种状态,访问过是一种状态,如果在dfs过程中访问到了正处于dfs状态的节点,则说明有环。
5. 深度优先遍历是说,在访问到一个新的节点之后,下一个节点继续去访问它的一个没被访问的邻居,直到所有邻居被访问之后,回退到上一个节点,继续访问没被访问过的邻居,大意上是说一条路走到头,在回头走另外一条路
6. 广度优先遍历,需要借助队列,与树的层次遍历类似,在入队的时候进行访问,出队的时候将出队元素的所有邻居节点(未被访问的)入队并访问,本题中,初始化队列的时候要注意入队的是所有入度为零的节点,意思是没有前置要求的课程,之后出队的时候,将它的相邻节点入度减一,代表相邻接点的前置需求被完成了一个,如果入度减为0,则入队表示可以选修该课程,如此以往到最后所有节点的入度是否都小于等于零,或者本题可以使用count计数选修的课程数来判断。

dfs

class Solution {
   
public:

    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
   
        int len = prerequisites.size();
        if(len<=1)return true;
        
        vector<vector<int>> adjacent(numCourses);
        vector<int> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值