1. 程式人生 > >【LeetCode】207. 課程表 結題報告 (C++)

【LeetCode】207. 課程表 結題報告 (C++)

原題地址:https://leetcode-cn.com/problems/course-schedule/description/

題目描述:

現在你總共有 n 門課需要選,記為 0 到 n-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。這是不可能的。
說明:

輸入的先決條件是由邊緣列表表示的圖形,而不是鄰接矩陣。詳情請參見圖的表示法。
你可以假定輸入的先決條件中沒有重複的邊。
提示:

這個問題相當於查詢一個迴圈是否存在於有向圖中。如果存在迴圈,則不存在拓撲排序,因此不可能選取所有課程進行學習。
通過 DFS 進行拓撲排序 - 一個關於Coursera的精彩視訊教程(21分鐘),介紹拓撲排序的基本概念。
拓撲排序也可以通過 BFS 完成。

 

解題方案:

這道題涉及了很多話題:dfs、bfs、圖以及拓撲排序。解題思路如下:

  • 首先構造有向圖,構造圖有三種方式:關聯矩陣,鄰接矩陣和鄰接表。這裡採用的是鄰接表,因為要採取很多的插入操作。
  • 接著,採用bfs進行拓撲排序,學習拓撲排序的方法,每次篩選時,刪除度為0的節點。
  • 最後是判定,若存在度不為0的節點,則說明存在著環。

程式碼:

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> heads(numCourses, -1), degree(numCourses, 0), points, args;
        pair<int, int> p;
        int from, to, count = 0, len = prerequisites.size();

        /* 構造有向圖,鄰接表 */
        for (int i = 0; i < len; ++i) {
            p = prerequisites[i];
            from = p.second;
            to = p.first;
            ++degree[to];
            args.push_back(heads[from]);
            points.push_back(to);
            heads[from] = count++;
        }

        /* bfs拓撲排序,依次移除入度為0的點 */
        queue<int> q;
        for (int i = 0; i < numCourses; ++i) 
            if (degree[i] == 0) q.push(i);
        while (!q.empty()) {
            from = q.front();
            q.pop();
            to = heads[from];
            while (to != -1) {
                if(--degree[points[to]] == 0) q.push(points[to]);
                to = args[to];
            }
        }

        /* 判定是否所有的點入度都為0,若是則不存在環,否則存在環 */
        for (int i = 0; i < numCourses; ++i)
            if (degree[i] > 0)
                 return false;

        return true;
    }
};

今天是10.24,程式設計師日??說實話,真的沒有感覺,對程式設計師沒啥認同感。。。

沒想到大家這麼重視,CSDN送一枚徽章還是美滋滋的,哈哈哈。。。