207. 課程表

Ethan3014發表於2020-12-19

描述

你這個學期必須選修 numCourse 門課程,記為 0 到 numCourse-1 。

在選修某些課程之前需要一些先修課程。 例如,想要學習課程 0 ,你需要先完成課程 1 ,我們用一個匹配來表示他們:[0,1]

給定課程總量以及它們的先決條件,請你判斷是否可能完成所有課程的學習?

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/course-schedule
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

solution

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class LeetCode {
    public static void main(String[] args) {
        Solution s = new Solution();
        int numCourses = 2;
        int [][] prerequisites = {
            {0,1},
            {1,0}
        };
        System.out.print(s.canFinish(numCourses, prerequisites));    
    }
}

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        Map<Integer, Set<Integer>> deps = new HashMap<Integer, Set<Integer>>();
        Set<Integer> finished = new HashSet<Integer>();

        for (int[] pre : prerequisites){
            Set<Integer> dep = deps.get(pre[0]);
            if (dep == null){
                dep = new HashSet<Integer>();
            }
            dep.add(pre[1]);
            deps.put(pre[0], dep);
        }

        System.out.println(deps);

        while(finishCourse(numCourses, deps, finished)){
            ;
        }

        if (finished.size() == numCourses){
            return true;
        }

        return false;
    }

    //每次遍歷一遍,找到可以完成的課程加入finished
    private boolean finishCourse(int numCourses, 
    Map<Integer, Set<Integer>> deps, Set<Integer> finished){
        boolean hasFinishedcourse = false;
        for (int i = 0; i < numCourses; i++){
            if (finished.contains(i)){
                continue;
            }

            Set<Integer> dep = deps.get(i);
            if (dep == null || finished.containsAll(dep)) {
                hasFinishedcourse = true;
                finished.add(i);
                //System.out.println("finish: " + i);
            }
        }

        return hasFinishedcourse;
    }
}

其他思路

這個解決方法裡finished.containsAll(dep)實際上是有重複計算的.
可以每次遍歷以後找出新的finished課程,就在dep裡面remove,另外待finish課程也應該使用集合,這樣演算法複雜度就是O(n)了

相關文章