Leetcode - Course Schedule

My code:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
    private int V = 0;
    private ArrayList<List<Integer>> adj;
    
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        V = numCourses;
        adj = new ArrayList<List<Integer>>();
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < prerequisites.length; i++) {
            adj.get(prerequisites[i][1]).add(prerequisites[i][0]);
        }
        
        int[] indegree = new int[V];
        for (int i = 0; i < V; i++) {
            for (Integer temp : adj.get(i)) {
                indegree[temp]++;
            }
        }
        
        Queue<Integer> q = new LinkedList<Integer>();
        for (int i = 0; i < V; i++) {
            if (indegree[i] == 0) {
                q.offer(i);
            }
        }
        
        if (q.isEmpty()) {
            return false;
        }
        
        int counter = 0;
        while (!q.isEmpty()) {
            Integer node = q.poll();
            for (Integer temp : adj.get(node)) {
                indegree[temp]--;
                if (indegree[temp] == 0) {
                    q.offer(temp);
                }
            }
            counter++;
        }
        
        if (counter != V) {
            return false;
        }
        else {
            return true;
        }
    }
}

這道題目的本質(zhì)在于及志,如何判斷一個圖中是否存在 circle

然后有兩種方法:
BFS, DFS

我個人更偏愛于 BFS

首相介紹下潜的,什么是 topological sort
就是將一堆有dependency 的結(jié)點(diǎn)按照先后順序輸出出來。
這個介紹的不錯则果。:
http://www.stoimen.com/blog/2012/10/01/computer-algorithms-topological-sort-of-a-graph/

必須是有向無環(huán)圖 DAG

如何表示一個有向圖厉亏〖叟酰可以是鏈表,也可以是稀疏矩陣

一個DAG让蕾,他一定至少有一個 入度為0的結(jié)點(diǎn)浪规,一個出度為0的結(jié)點(diǎn)。

所以涕俗,如果我們從入度入手罗丰,先把入度為0的結(jié)點(diǎn)刪除了。
然后再把刪除后重新成為入度為0的結(jié)點(diǎn)刪除了再姑。
依次循環(huán)萌抵,最后,如果,刪除的結(jié)點(diǎn)個數(shù)不等于圖總結(jié)點(diǎn)個數(shù)绍填,那么霎桅,就是有環(huán)圖。
http://www.geeksforgeeks.org/topological-sorting-indegree-based-solution/
這就是上面這個算法的思想讨永。
寫的還是很巧妙地滔驶。

下面說下 DFS
借鑒了這個思想:

http://www.geeksforgeeks.org/topological-sorting/

如果用 DFS實(shí)現(xiàn) topological sort
其實(shí)相比于BFS,更簡單卿闹,只用一味地DFS就行揭糕。

但是如果用來判斷是否有環(huán),就麻煩了锻霎。
于是我們需要維護(hù)一個set著角,然后每次進(jìn)入一個節(jié)點(diǎn),開始DFS
把訪問過的結(jié)點(diǎn)加入到set中旋恼,如果在這次dfs中吏口,之后又再次碰到了這個點(diǎn),那么就說明有重復(fù)冰更,有環(huán)产徊,就報(bào)錯。
如果沒問題蜀细,退回到這個結(jié)點(diǎn)的時(shí)候舟铜,千萬記得,把這個結(jié)點(diǎn)從set中刪去审葬,因?yàn)槠渌窂娇赡茉俅伟@個結(jié)點(diǎn)

同時(shí)深滚,還需要維護(hù)一個總的 布爾數(shù)組,來表示哪些結(jié)點(diǎn)已經(jīng)被訪問過了涣觉,不用再進(jìn)行判斷了痴荐。

My code:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
    private int V = 0;
    private ArrayList<List<Integer>> adj;
    
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        V = numCourses;
        adj = new ArrayList<List<Integer>>();
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < prerequisites.length; i++) {
            adj.get(prerequisites[i][1]).add(prerequisites[i][0]);
        }
        
        boolean[] isVisited = new boolean[V];
        for (int i = 0; i < V; i++) {
            if (!isVisited[i]) {
                boolean flag = visit(i, isVisited, new HashSet<Integer>());
                if (!flag) {
                    return false;
                }
            }
        }
        return true;
    }
    
    private boolean visit(int node, boolean[] isVisited, HashSet<Integer> set) {
        if (set.contains(node)) {
            return false;
        }
        set.add(node);
        isVisited[node] = true;
        for (Integer temp : adj.get(node)) {
            boolean flag = visit(temp, isVisited, set);
            if (!flag) {
                return false;
            }
        }
        set.remove(node);
        return true;
    }
}

reference:
https://discuss.leetcode.com/topic/17273/18-22-lines-c-bfs-dfs-solutions

Anyway, Good luck, Richardo! -- 09/09/2016

My code:

public class Solution {
    private Map<Integer, Set<Integer>> adj;
    private int[] degree;
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        adj = new HashMap<Integer, Set<Integer>>();
        degree = new int[numCourses];
        
        for (int i = 0; i < prerequisites.length; i++) {
            int src = prerequisites[i][1];
            int dest = prerequisites[i][0];
            if (!adj.containsKey(src)) {
                adj.put(src, new HashSet<Integer>());
            }
            if (!adj.get(src).contains(dest)) {
                adj.get(src).add(dest);
                degree[dest]++;
            }
        }
        
        Queue<Integer> q = new LinkedList<Integer>();
        for (int i = 0; i < numCourses; i++) {
            if (degree[i] == 0) {
                q.offer(i);
            }
        }
        
        int total = 0;
        while (!q.isEmpty()) {
            Integer curr = q.poll();
            total++;
            if (adj.containsKey(curr)) {
                for (Integer nei : adj.get(curr)) {
                    degree[nei]--;
                    if (degree[nei] == 0) {
                        q.offer(nei);
                    }
                }
            }
        }
        
        return total == numCourses;
    }
}

要注意,可能輸入邊會重復(fù), 所以要用set官册,并且初始化圖時(shí)要檢查生兆。
而且, [1] 是 src, [0] 是 dest

Anyway, Good luck, Richardo! -- 10/17/2016

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膝宁,一起剝皮案震驚了整個濱河市鸦难,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌员淫,老刑警劉巖合蔽,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異介返,居然都是意外死亡拴事,警方通過查閱死者的電腦和手機(jī)沃斤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刃宵,“玉大人衡瓶,你說我怎么就攤上這事∩ぃ” “怎么了哮针?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坦袍。 經(jīng)常有香客問我十厢,道長,這世上最難降的妖魔是什么捂齐? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任寿烟,我火速辦了婚禮,結(jié)果婚禮上辛燥,老公的妹妹穿的比我還像新娘。我一直安慰自己缝其,他們只是感情好挎塌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著内边,像睡著了一般榴都。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漠其,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天嘴高,我揣著相機(jī)與錄音,去河邊找鬼和屎。 笑死拴驮,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柴信。 我是一名探鬼主播套啤,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼随常!你這毒婦竟也來了潜沦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绪氛,失蹤者是張志新(化名)和其女友劉穎唆鸡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枣察,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡争占,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年燃逻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片燃乍。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡唆樊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刻蟹,到底是詐尸還是另有隱情逗旁,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布舆瘪,位于F島的核電站片效,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏英古。R本人自食惡果不足惜淀衣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望召调。 院中可真熱鬧膨桥,春花似錦、人聲如沸唠叛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽艺沼。三九已至册舞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間障般,已是汗流浹背调鲸。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挽荡,地道東北人藐石。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像徐伐,于是被迫代替她去往敵國和親贯钩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • My code: 其實(shí)就是 topological sort 實(shí)現(xiàn)一下办素。這是BFS版本 下面是DFS版本: 差不多...
    Richardo92閱讀 336評論 0 0
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)角雷。 張土汪:刷leetcod...
    土汪閱讀 12,747評論 0 33
  • 課程介紹 先修課:概率統(tǒng)計(jì),程序設(shè)計(jì)實(shí)習(xí)性穿,集合論與圖論 后續(xù)課:算法分析與設(shè)計(jì)勺三,編譯原理,操作系統(tǒng)需曾,數(shù)據(jù)庫概論吗坚,人...
    ShellyWhen閱讀 2,290評論 0 3
  • 因?yàn)橹熬蛷?fù)習(xí)完數(shù)據(jù)結(jié)構(gòu)了祈远,所以為了保持記憶,整理了一份復(fù)習(xí)綱要商源,復(fù)習(xí)的時(shí)候可以看著綱要想具體內(nèi)容车份。 樹 樹的基本...
    牛富貴兒閱讀 6,886評論 3 10
  • 今天第一件事就是去補(bǔ)牙了,下周還去一次牡彻,終于是快要告一段落了扫沼。補(bǔ)完回家,我整理東西庄吼,他玩沙畫缎除,互不干擾…… 下午閱...
    Jerryboy閱讀 152評論 0 1