[Leetcode]Course Schedule

本文介绍了解决课程安排问题的算法,使用拓扑排序确定学生能否完成所有课程,并提供了一种记录可行解决方案的方法。同时,还探讨了如何优化课程选择以满足时间限制条件。

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

Course Schedule

1

Course Schedule

According to the problem description, it is easily to find that we need to use Topological Sort to solve with the problem. Topological Sort is an easy algorithm. If a node without in-degree which means the node can be visited at any moment. If a node with one in-degree which means the node can be visited if and only if its father node has to be visited before it. So things are becoming easy. You can just keep a queue with all of the node without in-degree, and choose one from the queue at each time, then decrease the in-degree of nodes
which link with the node.

Stary 2017-10-18 at 6.49.22 P

#include <vector>
#include <queue>
using namespace std;
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> inDegree(numCourses, 0);
        vector<vector<int>> son(numCourses);
        for (int i = 0; i < prerequisites.size(); ++i) {
            inDegree[prerequisites[i].first]++;
            son[prerequisites[i].second].push_back(prerequisites[i].first);
        }
        queue<int> courseQueue;
        int finishedCourse = 0;
        for (int j = 0; j < numCourses; ++j) {
            if (inDegree[j] == 0) { courseQueue.push(j); finishedCourse++; }
        }
        while (!courseQueue.empty()) {
            int top = courseQueue.front();
            courseQueue.pop();
            for (int i = 0; i < son[top].size(); ++i) {
                inDegree[son[top][i]]--;
                if (inDegree[son[top][i]] == 0) {
                    finishedCourse++;
                    courseQueue.push(son[top][i]);
                }
            }
        }
        return finishedCourse == numCourses;
    }
};

2

Course Schedule II

The same as before, you just need to record the feasible solution.

#include <vector>
#include <iostream>
#include <queue>
using namespace std;
class Solution {
public:
    vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> inDegree(numCourses, 0);
        vector<vector<int>> son(numCourses);
        for (int i = 0; i < prerequisites.size(); ++i) {
            inDegree[prerequisites[i].first]++;
            son[prerequisites[i].second].push_back(prerequisites[i].first);
        }
        queue<int> courseQueue;
        int finishedCourse = 0;
        vector<int> ans;
        for (int j = 0; j < numCourses; ++j) {
            if (inDegree[j] == 0) { courseQueue.push(j); ans.push_back(j); finishedCourse++; }
        }
        while (!courseQueue.empty()) {
            int top = courseQueue.front();
            courseQueue.pop();
            for (int i = 0; i < son[top].size(); ++i) {
                inDegree[son[top][i]]--;
                if (inDegree[son[top][i]] == 0) {
                    ans.push_back(son[top][i]);
                    finishedCourse++;
                    courseQueue.push(son[top][i]);
                }
            }
        }
        return finishedCourse == numCourses ? ans : vector<int>{};
    }
};

3

Course Schedule III

Prove that:
condition:
d1 <= d2 <= d3 <= …. <= dm (after sorting)
to satisfy:
t1 <= d1
t1 + t2 <= d2
t1 + t2 + t3 <= d3
…..
t1 + t2 + t3 + …. + tm <= dm

Assume that we have t1 + t2 + t3 <= d3, but t1 + t2 + t3 + t4 > d4, then we need to remove the highest value of t[1:4], if it is t3, after that because t3 > t4, d3 < d4, t1 + t2 + t3 <= d3, we will absolutely conclude that t1 + t2 + t4 <= d3 <= d4. And we can find that 3 is the local optimal solution.

class Solution {
public:
    int scheduleCourse(vector<vector<int>>& courses) {
        vector<pair<int, int>> v;
        for (const vector<int>& c : courses) {
            v.emplace_back(c[1], c[0]);
        }
        sort(v.begin(), v.end());
        priority_queue<int> heap;
        int current = 0;
        for (int i = 0; i < v.size(); i++) {
            heap.push(v[i].second);
            current += v[i].second;
            if (current > v[i].first) {
                current -= heap.top();
                heap.pop();
            }
        }
        return heap.size();
    }
};
### LeetCode 拓扑排序题目解析 #### 课程表 (Course Schedule) 在LeetCode上的经典问题之一是《课程表》[^4]。该问题描述如下: 给定 `n`门课程以及一些先修课的要求,判断是否可以完成所有课程的学习。 ##### 思路分析 这个问题可以通过检测是否存在有向无环图(DAG)来解决。具体来说,如果能够找到一种拓扑排序方式,则意味着这些课程是可以按照一定顺序全部学完的;反之如果有环存在,则无法完成所有的课程学习。 为了实现这一点,通常会采用邻接矩阵或者邻接表的形式构建图结构,并利用深度优先搜索(DFS)[^2] 或广度优先搜索(BFS)[^1] 来尝试获得一个有效的拓扑序列。 对于BFS方法,在初始化阶段需要找出入度为零的节点加入队列中作为起点,之后不断移除当前处理过的节点并更新其他相连节点的入度直到遍历结束或发现矛盾为止[^5]。 ```java public boolean canFinish(int numCourses, int[][] prerequisites) { List<Integer>[] adj = new ArrayList[numCourses]; int[] indegrees = new int[numCourses]; // 构建邻接表和计算各结点入度数 for (int[] edge : prerequisites) { if (adj[edge[1]] == null) adj[edge[1]] = new ArrayList<>(); adj[edge[1]].add(edge[0]); ++indegrees[edge[0]]; } Queue<Integer> queue = new LinkedList<>(); // 将所有入度为0的顶点入队 for (int i = 0; i < numCourses; ++i){ if(indegrees[i]==0)queue.offer(i); } while(!queue.isEmpty()){ Integer cur=queue.poll(); --numCourses; if(adj[cur]!=null){ for(Integer next:adj[cur]){ if(--indegrees[next]==0){ queue.offer(next); } } } } return numCourses==0; } ``` 这段代码实现了基于Kahn算法(即宽度优先搜索)来进行拓扑排序的过程。它首先统计每个节点的入度数目,并把那些没有任何前驱依赖关系(也就是入度等于0)的节点放进初始队列里。接着逐个取出队首元素进行访问操作——减少其指向的目标节点们的剩余未满足条件数量(即减去它们各自的入度值)。一旦某个目标节点变得不再受约束(它的新入度变为0),就立即将这个节点追加到待处理集合当中继续考察下去。最终当整个流程结束后,只要还剩下没被触及过的东西就意味着原图中含有至少一个闭环路径,从而导致任务失败;否则便成功找到了一组可行方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值