欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

平行课程leetcode1136(拓扑排序)

程序员文章站 2022-04-01 16:52:43
...

已知有 N 门课程,它们以 1 到 N 进行编号。

给你一份课程关系表 relations[i] = [X, Y],用以表示课程 X 和课程 Y 之间的先修关系:课程 X 必须在课程 Y 之前修完。

假设在一个学期里,你可以学习任何数量的课程,但前提是你已经学习了将要学习的这些课程的所有先修课程。

请你返回学完全部课程所需的最少学期数。

如果没有办法做到学完全部这些课程的话,就返回 -1。

示例 1:
平行课程leetcode1136(拓扑排序)

输入:N = 3, relations = [[1,3],[2,3]]
输出:2
解释:
在第一个学期学习课程 1 和 2,在第二个学期学习课程 3。
示例 2:
平行课程leetcode1136(拓扑排序)

输入:N = 3, relations = [[1,2],[2,3],[3,1]]
输出:-1
解释:
没有课程可以学习,因为它们相互依赖。

提示:

1 <= N <= 5000
1 <= relations.length <= 5000
relations[i][0] != relations[i][1]
输入中没有重复的关系

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/parallel-courses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


public class 平行课程leetcode1136拓扑排序 {
    public static int minimumSemesters(int N, int[][] relations) {
        if (N < 1 || N > 5000 || relations == null ||
                relations.length < 1 || relations.length > 5000) {
            return -1;
        }
        int[] indegree = new int[N + 1];
        Map<Integer, Set<Integer>> adj = new HashMap<>();
        for (int i = 0; i < relations.length; i++) {
            indegree[relations[i][1]]++;   // 统计节点的入度
            if (adj.containsKey(relations[i][0])) {
                Set<Integer> sets = adj.get(relations[i][0]);
                sets.add(relations[i][1]);
                adj.put(relations[i][0], sets);
            } else {
                Set<Integer> tempSets = new HashSet<>();
                tempSets.add(relations[i][1]);
                adj.put(relations[i][0], tempSets);
            }
        }

        // 寻找入度为0的节点,
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 1; i < N + 1; i++) {
            if (indegree[i] == 0) {
                queue.add(i);
            }
        }


        int semester = 0;
        int finish_count = 0;

        while (queue.size() > 0) {
            semester += 1;
            Queue<Integer> newQueue = new LinkedList<>();
            for (Integer node : queue) {
                finish_count++;

                Set<Integer> sets = adj.get(node);
                if (sets != null) {
                    for (Integer neighbor : sets) {
                        // 将与这个节点相连的所有节点的入度减一
                        indegree[neighbor]--;
                        if (indegree[neighbor] == 0) {
                            newQueue.add(neighbor);
                        }
                    }
                }
            }
            queue = newQueue;
        }
        if (finish_count == N) {
            return semester;
        } else {
            return -1;
        }
    }

    public static void main(String[] args) {
//        System.out.println(minimumSemesters(25, new int[][]
//                {{5, 10}, {11, 14}, {21, 22}, {16, 19}, {21, 25}, {6, 18}, {1, 9}, {4, 7}, {10, 23}, {5, 14}, {9, 18}, {18, 21}, {11, 22}, {1, 15}, {1, 2}, {5, 18}, {7, 20}, {2, 23}, {12, 13}, {9, 14}, {10, 16}, {11, 21}, {5, 12}, {2, 24}, {8, 17}, {15, 17}, {10, 13}, {11, 16}, {20, 22}, {7, 11}, {9, 15}, {16, 22}, {18, 20}, {19, 22}, {10, 18}, {3, 20}, {16, 25}, {10, 15}, {1, 23}, {13, 16}, {23, 25}, {1, 8}, {4, 10}, {19, 24}, {11, 20}, {3, 18}, {6, 25}, {11, 13}, {13, 15}, {22, 24}, {6, 24}, {17, 20}, {2, 25}, {15, 24}, {8, 21}, {14, 16}, {5, 16}, {19, 23}, {1, 5}, {4, 22}, {19, 20}, {12, 15}, {16, 18}, {9, 13}, {13, 22}, {14, 22}, {2, 8}, {3, 13}, {9, 23}, {14, 15}, {14, 17}, {8, 20}, {9, 17}, {3, 19}, {8, 25}, {2, 12}, {7, 24}, {19, 25}, {1, 13}, {6, 11}, {14, 21}, {7, 15}, {3, 14}, {15, 23}, {10, 17}, {4, 20}, {6, 14}, {10, 21}, {2, 13}, {3, 21}, {8, 11}, {5, 21}, {6, 23}, {17, 25}, {16, 21}, {12, 22}, {1, 16}, {6, 19}, {7, 25}, {3, 23}, {11, 25}, {3, 10}, {6, 7}, {2, 3}, {5, 25}, {1, 6}, {4, 17}, {2, 16}, {13, 17}, {17, 22}, {6, 13}, {5, 6}, {4, 11}, {4, 23}, {4, 8}, {12, 23}, {7, 21}, {5, 20}, {3, 24}, {2, 10}, {13, 14}, {11, 24}, {1, 3}, {2, 7}, {7, 23}, {6, 17}, {5, 17}, {16, 17}, {8, 15}, {8, 23}, {7, 17}, {14, 18}, {16, 23}, {23, 24}, {4, 12}, {17, 19}, {5, 9}, {10, 11}, {5, 23}, {2, 9}, {1, 19}, {2, 19}, {12, 20}, {2, 14}, {11, 12}, {1, 12}, {13, 23}, {4, 9}, {7, 13}, {15, 20}, {21, 24}, {8, 18}, {9, 11}, {8, 19}, {6, 22}, {16, 20}, {22, 25}, {20, 21}, {6, 16}, {3, 17}, {1, 22}, {9, 22}, {20, 24}, {2, 6}, {9, 16}, {2, 4}, {2, 20}, {20, 25}, {9, 10}, {3, 11}, {15, 18}, {1, 20}, {3, 6}, {8, 14}, {10, 22}, {12, 21}, {7, 8}, {8, 16}, {9, 20}, {3, 8}, {15, 21}, {17, 21}, {11, 18}, {13, 24}, {17, 24}, {6, 20}, {4, 15}, {6, 15}, {3, 22}, {13, 21}, {2, 22}, {13, 25}, {9, 12}, {4, 19}, {1, 24}, {12, 19}, {5, 8}, {1, 7}, {3, 16}, {3, 5}, {12, 24}, {3, 12}, {2, 17}, {18, 22}, {4, 25}, {8, 24}, {15, 19}, {18, 23}, {1, 4}, {1, 21}, {10, 24}, {20, 23}, {4, 14}, {16, 24}, {10, 20}, {18, 24}, {1, 14}, {12, 14}, {10, 12}, {4, 16}, {5, 19}, {4, 5}, {19, 21}, {15, 25}, {1, 18}, {2, 21}, {4, 24}, {7, 14}, {4, 6}, {15, 16}, {3, 7}, {21, 23}, {1, 17}, {12, 16}, {13, 18}, {5, 7}, {9, 19}, {2, 15}, {22, 23}, {7, 19}, {17, 23}, {8, 22}, {11, 17}, {7, 16}, {8, 9}, {6, 21}, {4, 21}, {4, 13}, {14, 24}, {3, 4}, {7, 18}, {11, 15}, {5, 11}, {12, 17}, {6, 9}, {1, 25}, {12, 18}, {6, 12}, {8, 10}, {6, 8}, {11, 23}, {7, 10}, {14, 25}, {14, 23}, {12, 25}, {5, 24}, {10, 19}, {3, 25}, {7, 9}, {8, 12}, {5, 22}, {24, 25}, {13, 19}, {3, 15}, {5, 15}, {15, 22}, {10, 14}, {3, 9}, {13, 20}, {1, 10}, {9, 21}, {10, 25}, {9, 24}, {14, 20}, {9, 25}, {8, 13}, {7, 12}, {5, 13}, {6, 10}, {2, 5}, {2, 18}, {14, 19}, {1, 11}, {7, 22}, {18, 25}, {11, 19}, {18, 19}, {4, 18}, {17, 18}, {2, 11}}));

        System.out.println(minimumSemesters(3,new int[][]{{1,2},{2,3},{3,1}}));
    }
}

相关标签: 平行课程