Leetcode編程練習:課程編排

題目原文:(id=210)

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, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

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 the correct course order is [0,1]

4, [[1,0],[2,0],[3,1],[3,2]]

There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3].

簡單來說,就是輸入一些課程的先後修的關係,要求找到一種可行的修課程的順序,是有向無環圖拓撲排序的一個典型運用。首先在輸入時把邊錶轉化爲鄰接矩陣,同時求出(初始化)各個頂點的入度(也就是每一門課程參與前要修完的課程種類數),如果沒有入度爲0的點,則肯定沒有合法的解,否則將入度爲0的頂點存儲在一個隊列中。然後將隊列中頂點逐個取出,把所有當前頂點指向的頂點的入度減1,如果它們變成0則放到隊列當中,直到所有元素都出隊。頂點出隊的順序顯然就是圖的一個拓撲排序。這個算法時間複雜度爲O(E)

vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        int n = numCourses;
		vector<vector<int> > adj(n);
		vector<int> indegree(n, 0);
		for (int i = 0;i < prerequisites.size();i++) {
			adj[prerequisites[i].second].push_back(prerequisites[i].first);
			indegree[prerequisites[i].first]++;
		}
		vector<int> seq;
		queue<int> open;
		for (int i = 0;i < n;i++) {
			if (indegree[i] == 0) {
				open.push(i);
				seq.push_back(i);
			}
		}
		while (open.size()) {
			int pos = open.front();
			open.pop();
			for (int i = 0;i < adj[pos].size();i++) {
				int nw = adj[pos][i];
				indegree[nw]--;
				if (indegree[nw] == 0) {
					open.push(nw);
					seq.push_back(nw);
				}
			}
		}
		if (seq.size() == n) return seq;
		else return vector<int>();
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章