Leetcode Course Schedule

Leetcode207 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?

題意
共有n門課程需要學習,課程編號從0至n-1。
有些課程有先修要求,比如必須先修課程1後修課程0,用[0, 1]表示。
給出總課程數和先後修要求對,判斷是否有可能完成所有課程。

分析
很顯然,這是一個有向無環圖的判斷問題。只要所有課程中出現了環,就不可能修滿所有課程。有向無環圖的判斷可採用dfs或bfs,至於生成圖的形式可以是鄰接矩陣,也可以是鄰接表。爲了減小時間複雜度,本題考慮採用鄰接表的方法。

注意
如果採用鄰接矩陣可能會導致時間超限。另外可以採用bfs的方法求是否有環。基本思路就是將入度爲0的課程放入隊列。直到所有課程都被完成或發現一個環。

基本步驟
1. 將每個先後修要求對導入鄰接表中。
2. 將使用dfs判斷是否無環:
2.1 用isVisited記錄各個課程是否被訪問過;
2.2 用onStack記錄一條路徑上的課程,判斷是否有環;
2.3 有環返回true,無環繼續;
3. 如有環主函數返回false,否則返回true。

AC代碼

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        if (!prerequisites.size()) return true;
        vector<vector<int>> map(numCourses, vector<int>());
        for (int i = 0; i < prerequisites.size(); ++i) {
            map[prerequisites[i][0]].push_back(prerequisites[i][1]);
        }
        vector<bool> isVisited(numCourses, false);
        for (int i = 0; i < numCourses; ++i) {
            if (!isVisited[i]) {
                vector<bool> onStack(numCourses, false);
                if (hasCycle(map, i, isVisited, onStack))
                    return false;
            }
        }
        return true;
    }
    bool hasCycle(vector<vector<int>> &map, int i, vector<bool> &isVisited, vector<bool> &onStack) {
        isVisited[i] = true;
        onStack[i] = true;
        for (int k : map[i]) {
            if (onStack[k])
                return true;
            else
                if (hasCycle(map, k, isVisited, onStack))
                    return true;
        }
        onStack[i] = false;
        return false;
    }
};

如代碼或分析有誤,請批評指正,謝謝。

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