[LeetCode刷题日记(Day25)]:Course Schedule

本文深入探讨了一种解决课程调度问题的算法,通过构建图结构和使用队列来判断是否能够合理安排所有课程,避免课程间的前置条件冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem 207. Course Schedule

  • 题目描述
    There are a total of n courses you have to take, labeled from 0 to n-1.

    Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

    Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

    Example 2:

    Input: 2, [[1,0],[0,1]]
    Output: false
    Explanation: There are a total of 2 courses to take. 
                 To take course 1 you should have finished course 0, and to take course 0 you should
                 also have finished course 1. So it is impossible.
    
  • 解题思路
    题目意思是有 n 门课,课程编号分别为 0 到 n-1,现在给定二维数组 prerequisites 表示课程之间的约束关系,例如 prerequisites[0] = [0, 1] 表示只有先上了课程1之后才能上课程 0,问能否找到一个合适的排课方案。解题思路如下:

  1. 建立一个二维 vector 对象 graph,其中 graph[i] 表示以 i 为先导课程的所有课程的集合;建立一维 vector 变量 requireNum,其中 requireNum[i] 表示课程 i 需要的先导课程的数量。
  2. 建立一个队列 q,对 requireNum 进行遍历,将 requireNum[i] = 0 的所有课程编号 i 存入队列 q中。此时 q 中的元素表示可以直接开课的课程(无需先导课程或先导课程已修的课程)。
  3. 对 q 中的所有元素 cur 进行遍历,每访问完一个 cur 表示课程 cur 已经修完。此时将 graph[cur] 中的每一个元素的 requireNum 值减 1,表示该课程需要的先导课程数量减 1,若所需先导课程数量变为 0,表示此课程可以上了,并加入到队列 q 中。
  4. 对 q 中所有的元素进行遍历后,检查 requireNum 中每一个元素的值,如果出现不为 0 的情况,则表示至少有一门课无法安排上课,返回 false。
  • 代码实现
    该算法的 C++ 代码如下:
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {
        vector<vector<int> > graph(numCourses, vector<int>(0));
        vector<int> requireNum(numCourses, 0);

        for(auto pre : prerequisites){
        	graph[pre.second].push_back(pre.first);
        	requireNum[pre.first]++; 
        }

        queue<int> q;
        for(int i = 0; i < requireNum.size(); ++i)
        	if(requireNum[i] == 0)
        		q.push(i);

        while(!q.empty()){
        	int cur = q.front();
        	q.pop();
        	for(auto i : graph[cur]){
        		requireNum[i]--;
        		if(requireNum[i] == 0)
        			q.push(i);
        	}
        }
        for(auto i : requireNum)
        	if(i != 0)
        		return false;
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值