207. Course Schedule

本文探讨了如何判断能否完成所有课程的问题,通过拓扑排序来确定是否存在选课顺序上的闭环,进而判断是否能够顺利完成所有课程。

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

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?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

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.

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

click to show more hints.

Subscribe to see which companies asked this question.


给出数字n代表有n门课,编号0~n-1,一些课是有要求要先上一些别的课,问是否能修完全部课。这里能修完就相当于需求图中没有回环,所以可以用拓扑排序的方法解决问题。先找一个入度为0的节点,把它摘除,然后他指向的节点的入度就减一,减一的过程中如果有节点的入度变为0,就入栈,方便下次的摘除;然后循环摘除节点,直到没有入度为0的节点为止。循环过程中进行计数,如果摘除的节点个数小于所有节点数,说明图中有环,返回false,否则返回true。


代码:

class Solution
{
public:
	bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) 
	{
		vector<vector<int> > graph(numCourses);
		vector<int> in_cnt(numCourses);
		for(int i = 0; i < prerequisites.size(); ++i)
		{
			graph[prerequisites[i].first].push_back(prerequisites[i].second);
			in_cnt[prerequisites[i].second]++;
		}

		stack<int> stk;
		int cnt = 0;
		for(int i = 0; i < numCourses; ++i)
		{
			if(in_cnt[i] == 0) stk.push(i);
		}

		while(!stk.empty())
		{
			int cur = stk.top();
			stk.pop();
			++cnt;

			for(int i = 0; i < graph[cur].size(); ++i)
			{
				if(--in_cnt[graph[cur][i]] == 0)
				{
					stk.push(graph[cur][i]);
				}
			}
		}

		return cnt >= numCourses;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值