LeetCode 207.課程表(拓撲排序)

力扣鏈接LeetCode

1、 題目:

你這個學期必須選修 numCourse 門課程,記爲 0 到 numCourse-1 。
在選修某些課程之前需要一些先修課程。 例如,想要學習課程 0 ,你需要先完成課程 1 ,我們用一個匹配來表示他們:[0,1]
給定課程總量以及它們的先決條件,請你判斷是否可能完成所有課程的學習?
測試用例:

示例1:輸入: 2, [[1,0]] 
輸出: true
解釋: 總共有 2 門課程。學習課程 1 之前,你需要完成課程 0。所以這是可能的。
示例2:輸入: 2, [[1,0],[0,1]]
輸出: false
解釋: 總共有 2 門課程。學習課程 1 之前,你需要先完成​課程 0;並且學習課程 0 之前,你還應先完成課程 1。這是不可能的

2、分析

這是一個有向圖,能完成所有課程的學習得要求有向圖中無環。圖表示分爲順序存儲(鄰接矩陣)和鏈式存儲(鄰接表)。這裏選擇鏈式存儲,鄰接表

3、思路

通過拓撲排序判斷此課程安排圖是否是有向無環圖。
拓撲排序原理: 對 DAG 的頂點進行排序,使得對每一條有向邊 (u,v),均有 u(在排序記錄中)比 v先出現。亦可理解爲對某點 v而言,只有當 v的所有源點均出現了,v才能出現。

兩種方法:

1、廣度優先搜索

在這裏插入圖片描述
代碼:

class Solution{
    public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        int num=numCourses;
        vector<int> in_degree(numCourses,0); //用來保存所有頂點的入度
        vector<vector<int>> adjGraph(numCourses); // 存儲鄰接表
        queue<int> q;

        for(int i=0;i<prerequisites.size();i++){
            in_degree[prerequisites[i][0]]++;
            adjGraph[prerequisites[i][1]].push_back(prerequisites[i][0]);
        }

        // 將入度爲0 點的點壓棧
        for(int i=0;i<numCourses;i++){
            if(in_degree[i]==0){
                q.push(i);
                num--;
            }
        }

        while(!q.empty()){
            int temp=q.front();
            q.pop();
            for(int i=0;i<adjGraph[temp].size();i++){
                if((--in_degree[adjGraph[temp][i]])==0){
                    q.push(adjGraph[temp][i]);
                    num--;
                }
            }
        }
        if(num==0){
            return true;
        }
        return false;
    }
};

2、深度優先搜索

在這裏插入圖片描述
代碼:

class Solution{
    public:
        bool canFinish(int numCourses, vector<vector<int>>& prerequisites){
            vector<int> flag(numCourses,0);
            vector<vector<int>> adjacency(numCourses);

            for(int i=0;i<prerequisites.size();i++){
                adjacency[prerequisites[i][1]].push_back(prerequisites[i][0]);
            }

            for(int i=0;i<numCourses;i++){
                if(dfs(i,adjacency,flag)==false){
                    return false;
                }
            }
            return true;

        }
        bool dfs(int i,vector<vector<int>> &adjacency,vector<int> & flag){
            if(flag[i]==-1){
                return true;
            }
            if(flag[i]==1){
                return false;
            }
            flag[i]=1;
            for(int j=0;j<adjacency[i].size();j++){
                if(dfs(adjacency[i][j],adjacency,flag)==false){
                    return false;
                }
            }
            flag[i]=-1;
            return true;
        }
};

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