LintCode 安排課程

你需要去上n門九章的課才能獲得offer,這些課被標號爲 0 到 n-1 。
有一些課程需要“前置課程”,比如如果你要上課程0,你需要先學課程1,我們用一個匹配來表示他們: [0,1]

給你課程的總數量和一些前置課程的需求,返回你爲了學完所有課程所安排的學習順序。

可能會有多個正確的順序,你只要返回一種就可以了。如果不可能完成所有課程,返回一個空數組。

樣例

給定 n = 2, prerequisites = [[1,0]]
返回 [0,1]

給定 n = 4, prerequisites = [1,0],[2,0],[3,1],[3,2]]
返回 [0,1,2,3] or [0,2,1,3]

思路

拓撲排序,採用寬度優先搜索的方式。

遍歷找出每門課有幾門前置課,以及它所有的後置課。

找出前置課門數爲 0 可以直接上的課程,將他們的後置課的前置課門數減 1,若減 1 後前置課門數爲 0 了表示這門課也能上了,加入到下一輪要上的課程之中。如此反覆,上完所有能上的課,若門數與總門數相同則可以完成課程,返回完成順序,不同則不能完成,返回空數組。

參考拓撲排序算法 http://blog.csdn.net/dm_vincent/article/details/7714519

    vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> r; r.reserve(numCourses);
        vector<int> indegrees(numCourses, 0);
        vector<vector<int>> childs; childs.resize(numCourses);
        for(int i = 0; i < prerequisites.size(); ++i) {
            pair<int, int>& t = prerequisites[i];
            ++indegrees[t.first];
            childs[t.second].push_back(t.first);
        }
        vector<int>* buf = new vector<int>();
        vector<int>* buf2 = new vector<int>();
        for(int i = 0; i < numCourses; ++i) {
            if(indegrees[i] == 0) {
                r.push_back(i);
                buf->push_back(i);
            }
        }
        while(buf->size()) {
            buf2->clear();
            for(int i = 0; i < buf->size(); ++i) {
                vector<int>& arr = childs[(*buf)[i]];    
                for(int j = 0; j < arr.size(); ++j) {
                    if(--indegrees[arr[j]] == 0) {
                        r.push_back(arr[j]);
                        buf2->push_back(arr[j]);
                    }
                }
            }
            vector<int>* tmp = buf;
            buf = buf2;
            buf2 = tmp;
        }
        if(r.size() < numCourses) return vector<int>();
        return r;
    }


發佈了69 篇原創文章 · 獲贊 45 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章