算法课第3周第2题——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?

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.


程序代码:

class Solution {
public:
	bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
		map<int, vector<int>> m;

		// 将课程转化为图,用邻接表表示,m[t]中为完成课程t后才能进行的课程
		for (int i = 0; i < prerequisites.size(); i++) {
			m[prerequisites[i].second].push_back(prerequisites[i].first);
		}

		// 用拓扑排序的思想
		// 用向量记录每个顶点i的入度
		vector<int> v(numCourses, 0); // numCourses个向量,初始化为0
		for (int i = 0; i < numCourses; i++) {
			for (int j = 0; j < m[i].size(); j++) {
				v[m[i][j]]++;
			}
		}

		// 遍历numCourses次
		for (int n = 0; n < numCourses; n++) {
			// 找到入度为0的点
			for (int i = 0; i < numCourses; i++) {
				// 若点i入度为0
				if (v[i] == 0) {
					v[i] = -1; // 标记为-1,表示将该点去掉

					// 该点的边全部去掉,相应点的入度都-1
					for (int j = 0; j < m[i].size(); j++) {
						v[m[i][j]]--;
					}
				}
			}
		}

		// 若还有入度不为0或标记为-1的点,则不是DAG,返回false. 否则返回true
		for (int i = 0; i < numCourses; i++) {
			if (v[i] != 0 && v[i] != -1) {
				return false;
			}
		}
		return true;
	}
};


简要题解:

本题主要是有关图和拓扑排序算法的问题。

先理清题意。给出0到n-1编号的课程,并给出一系列数对[x,y],表示要上x课程需要先完成y课程,最后需要判断是否能够完成所有课程。根据题意,可以使用拓扑排序的思想来解决这个问题。

首先将课程转化为图,使用邻接表来进行表示(这里用到了STL库中的map来实现邻接表,由整数 t 映射到向量m[t],m[t]中为完成课程 t 后才能进行的课程)。将课程转化为图的表示后,再通过遍历邻接表,用一个向量 v 来记录每个顶点的入度。接着,再对邻接表遍历numCourses次,每一次都找到入度为0的点 i, 将其入度v[i] 标记为-1(表示将该点从图中去掉),并将该点出发的边全部去掉,即这些边指向的点的入度都减去1. 这样操作过后,若还有入度不为0或标记为-1的点,则不是DAG,返回false. 否则返回true。

通过本题,我很好的复习了本周所学的图及拓扑排序的有关内容。对于这些有关活动先后顺序的题目,可以考虑一下是否可以使用拓扑排序来解答。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值