Leetcode 第207題:Course Schedule--安排課程表(C++、Python)

題目地址:Course Schedule


題目簡介:

現在你總共有 n 門課需要選,記爲 0 到 n-1。但是在選修某些課程之前需要一些先修課程, 例如,想要學習高等數學,你需要先學完高中數學。

我們用一個匹配來表示他們: [0,1]給定課程總量以及它們的先決條件,判斷是否可能完成所有課程的學習?

Example 1:
Input: 2, [[1,0]] 
Output: true
Explanation: 總共有 2 門課程,學習課程 1 之前,你需要完成課程 0,所以這是可能的。

Example 2:
Input: 2, [[1,0],[0,1]]
Output: false
Explanation: 總共有 2 門課程,學習課程 1 之前,你需要先完成​課程 0;並且學習課程 0 之前,你還應先完成課程 1,這是不可能的。

說明:輸入的先決條件是由邊緣列表表示的圖形,而不是鄰接矩陣,詳情請參見圖的表示法。

可以假定輸入的先決條件中沒有重複的邊。

提示:這個問題相當於查找一個循環是否存在於有向圖中。如果存在循環,則不存在拓撲排序,因此不可能選取所有課程進行學習。


題目解析:

1、有向無環圖

數據結構中的有向無環圖,即所有點之間的關聯都是單向的,並且不會出現環。拓撲排序是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u(先決課)和v(後上課),若邊(u,v)∈E(G),則u在線性序列中出現在v之前。

整體的步驟如下:

(1) 選擇一個入度爲0的頂點並輸出之;

(2) 從網中刪除此頂點及所有出邊

 

 

循環結束後,若輸出的頂點數小於網中的頂點數,則輸出“有迴路”信息,否則輸出的頂點序列就是一種拓撲序列

C++版:

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int> > relation(numCourses, vector<int>(0));
        vector<int> waiting(numCourses, 0);
        for (auto cur : prerequisites) 
        {
            relation[cur[1]].push_back(cur[0]);
            waiting[cur[0]]++;
        }
        queue<int> done; //存放當前可以上的課程
        for (int i = 0; i < numCourses; ++i) 
        {
            if (waiting[i] == 0) 
                done.push(i);
        }
        while (!done.empty()) 
        {
            int finished = done.front();
            done.pop();
            for (auto a : relation[finished]) 
            {
                waiting[a]--;
                if (waiting[a] == 0) 
                    done.push(a);
            }
        }
        for (int i = 0; i < numCourses; ++i) 
        {
            if (waiting[i] != 0) 
                return false;
        }
        return true;
    }
};

Python代碼參考:Python3 BFS faster than 96.75%

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        relation = collections.defaultdict(list)
        waiting = [0 for i in range(numCourses)]
        
        for cur in prerequisites:
            relation[cur[1]].append(cur[0])
            waiting[cur[0]] += 1
        
        queue = []
        for i in relation:
            if waiting[i] == 0:
                queue.append(i)
        while queue!=[]:
            done = queue.pop()
            for sche in relation[done]:
                waiting[sche] -= 1
                if waiting[sche] == 0:
                    queue.append(sche)
        for t in waiting:
            if waiting[t]!=0:
                return False
        return True

 

 

 

 

 

 

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