1. 程式人生 > 其它 >leetcode 207. 課程表

leetcode 207. 課程表

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

在選修某些課程之前需要一些先修課程。 先修課程按陣列prerequisites 給出,其中prerequisites[i] = [ai, bi] ,表示如果要學習課程ai 則 必須 先學習課程 bi 。

例如,先修課程對[0, 1] 表示:想要學習課程 0 ,你需要先完成課程 1 。
請你判斷是否可能完成所有課程的學習?如果可以,返回 true ;否則,返回 false 。

示例 1:

輸入:numCourses = 2, prerequisites = [[1,0]]
輸出:true
解釋:總共有 2 門課程。學習課程 1 之前,你需要完成課程 0 。這是可能的。
示例 2:

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

提示:

1 <= numCourses <= 105
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
prerequisites[i] 中的所有課程對 互不相同

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

1:用Map<Integer, List<Integer>> all 來記錄需要課之間的關係。
2:用Map<Integer, Integer> map來記錄每個節點的引用次數v。
3:吧次數為0的節點放入棧中, 並把all中對應的節點的次數v都-1.
4:若v== 0,則放入棧中。
5:最終棧中沒有元素,並且所有的節點都從棧中彈出過,則說明符合要求。

    public boolean canFinish(int numCourses, int[][] prerequisites) {
        if (prerequisites == null || prerequisites.length == 0 || prerequisites[0].length == 0) {
            
return true; } int length = prerequisites.length; Stack<Integer> stack = new Stack<>(); Map<Integer, Integer> map = new HashMap<>(); Map<Integer, List<Integer>> all = new HashMap<>(); for (int i = 0; i < length; i++) { int[] arr = prerequisites[i]; List<Integer> item = all.computeIfAbsent(arr[0], k -> new ArrayList<>()); item.add(arr[1]); map.putIfAbsent(arr[0], 0); map.merge(arr[1], 1, (a, b) -> a + b); } for (Map.Entry<Integer, Integer> entry : map.entrySet()) { if (entry.getValue() == 0) { stack.add(entry.getKey()); } } int count = 0; int size = map.size(); while (!stack.isEmpty() && count < size) { Integer pop = stack.pop(); List<Integer> list = all.get(pop); count++; if (list == null) { continue; } for (Integer item : list) { int v = map.get(item) - 1; if (v == 0) { stack.add(item); } map.put(item, v); } } return stack.isEmpty() && count == size; }