iT邦幫忙

2025 iThome 鐵人賽

0
自我挑戰組

leetcode解題學習java系列 第 27

30天LeetCode挑戰紀錄-DAY27. Course Schedule

  • 分享至 

  • xImage
  •  

題目

https://ithelp.ithome.com.tw/upload/images/20251020/20178158aIYFFr8LF1.png
我總共有numCourses門課(0到n-1),和一個先修課程列表prerequisites[i]=[ai,bi],a代表的是我想修的課,b表示我必需先修的課。
然後我要做的就是判斷我是否有修完所有課程。

那我這次參考的程式碼是用Kahn演算法
它模擬了我們「修課」的過程:
找出所有可以直接修的課,就是這些是沒有任何先修課程要求的課。

  1. 開始修課: 把這些課修完。
  2. 更新依賴: 這些課修完後,它們作為「先修課」的任務就達成了。
  3. 尋找新的「可以修」的課: 看看哪些課,它們的「所有」先修課都已經被你修完了。
  4. 重複 2-4 步,不斷修課,直到沒有課可以修為止。
    最後,如果修完的「總課程數」等於 n,代表成功修完了所有課。
    如果小於 n,代表有課卡住了(因為它們在一個環裡)。
    https://ithelp.ithome.com.tw/upload/images/20251020/20178158kgf8XMZQSU.png

程式碼

class Solution {
    public boolean canFinish(int n, int[][] prerequisites) {
        
        List<Integer>[] adj = new List[n];// adj[i]:以 i 為先修課的課程清單
        int[] indegree = new int[n];  // indegree[i]:課程 i 需要的先修課數量

        // 建立圖
        for (int[] p : prerequisites) {
            int course = p[0], pre = p[1];
            if (adj[pre] == null) adj[pre] = new ArrayList<>();
            adj[pre].add(course);
            indegree[course]++;
        }

        // 將指向a的邊為 0的課放入 queue
        Queue<Integer> q = new LinkedList<>();
        for (int i = 0; i < n; i++)
            if (indegree[i] == 0) q.offer(i);

        // BFS 拓撲排序
        int count = 0; // 已修課程數
        while (!q.isEmpty()) {
            int cur = q.poll();
            count++;
            if (adj[cur] != null) {
                for (int next : adj[cur]) {
                    if (--indegree[next] == 0) q.offer(next);
                }
            }
        }

        // 修完所有課,無環,回傳 true
        return count == n;
    }
}

程式碼引用:
https://leetcode.com/problems/course-schedule/solutions/3756938/beat-s-100-topo-c-java-python-beginner-friendly


上一篇
30天LeetCode挑戰紀錄-DAY26. Is Graph Bipartite?
下一篇
30天LeetCode挑戰紀錄-DAY28. Shortest Path in Binary Matrix
系列文
leetcode解題學習java30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言