[LeetCode] 1462. Course Schedule IV
There are a total of numCourses
courses you have to take, labeled from 0
to numCourses - 1
. You are given an array prerequisites
where prerequisites[i] = [ai, bi]
indicates that you must take course ai
first if you want to take course bi
.
- For example, the pair
[0, 1]
indicates that you have to take course0
before you can take course1
.
Prerequisites can also be indirect. If course a
is a prerequisite of course b
, and course b
is a prerequisite of course c
, then course a
is a prerequisite of course c
.
You are also given an array queries
where queries[j] = [uj, vj]
. For the jth
query, you should answer whether course uj
is a prerequisite of course vj
or not.
Return a boolean array answer
, where answer[j]
is the answer to the jth
query.
Example 1:
Input: numCourses = 2, prerequisites = [[1,0]], queries = [[0,1],[1,0]] Output: [false,true] Explanation: The pair [1, 0] indicates that you have to take course 1 before you can take course 0. Course 0 is not a prerequisite of course 1, but the opposite is true.
Example 2:
Input: numCourses = 2, prerequisites = [], queries = [[1,0],[0,1]] Output: [false,false] Explanation: There are no prerequisites, and each course is independent.
Example 3:
Input: numCourses = 3, prerequisites = [[1,2],[1,0],[2,0]], queries = [[1,0],[1,2]] Output: [true,true]
Constraints:
2 <= numCourses <= 100
0 <= prerequisites.length <= (numCourses * (numCourses - 1) / 2)
prerequisites[i].length == 2
0 <= ai, bi <= n - 1
ai != bi
- All the pairs
[ai, bi]
are unique. - The prerequisites graph has no cycles.
1 <= queries.length <= 104
0 <= ui, vi <= n - 1
ui != vi
课程表 IV。
你总共需要上
numCourses
门课,课程编号依次为0
到numCourses-1
。你会得到一个数组prerequisite
,其中prerequisites[i] = [ai, bi]
表示如果你想选bi
课程,你 必须 先选ai
课程。
- 有的课会有直接的先修课程,比如如果想上课程
1
,你必须先上课程0
,那么会以[0,1]
数对的形式给出先修课程数对。先决条件也可以是 间接 的。如果课程
a
是课程b
的先决条件,课程b
是课程c
的先决条件,那么课程a
就是课程c
的先决条件。你也得到一个数组
queries
,其中queries[j] = [uj, vj]
。对于第j
个查询,您应该回答课程uj
是否是课程vj
的先决条件。返回一个布尔数组
answer
,其中answer[j]
是第j
个查询的答案。
思路是拓扑排序。对于这道题,你需要一个入度表 indegree 记录课程的入度和两个 hashmap,一个 adj 哈希表用来记录课程之间的邻接关系;一个 preMap 哈希表用来记录课程之间的先修关系。首先对于每一个课程 i ,我们需要为这个课程在邻接表和先修表里创建一个 hashset 以记录课程之间的关系。
接着遍历直接先修课程数对列表 prerequisite,记录课程的入度,同时也记录各个课程的邻接关系。接着还是跟之前的课程安排的题一样,把入度为 0 的课程加入queue,意思是从不需要先修课程的课开始找起,去创建课程之间的先修关系。从 queue 弹出一个课程 cur 的时候,从邻接哈希表 adj 拿到 cur 的所有邻接课程,同时因为 cur 的入度为 0 所以对于每一个 next 课程而言,cur 课程一定是 next 的先修课程,所以我们在 preMap 里找到 next ,并且把 cur 加入 next 的先修课程里。同时如果 cur 自己也有先修课程,也需要把他们统统加入 next 的先修课程的 hashset 里。
最后对于需要判断的 queries,因为 queries[0] 是先修课程,queries[1] 是后继课程,所以判断的方式是看看 preMap 里 key 为 queries[0] 的 hashset 是否包含 queries[1]。
时间O(n^2)
空间O(n)
Java实现
1 class Solution { 2 public List<Boolean> checkIfPrerequisite(int n, int[][] prerequisites, int[][] queries) { 3 int[] indegree = new int[n]; 4 HashMap<Integer, Set<Integer>> adj = new HashMap<>(); 5 HashMap<Integer, Set<Integer>> preMap = new HashMap<>(); 6 for (int i = 0; i < n; i++) { 7 preMap.put(i, new HashSet<>()); 8 adj.put(i, new HashSet<>()); 9 } 10 for (int[] pre : prerequisites) { 11 indegree[pre[1]]++; 12 adj.get(pre[0]).add(pre[1]); 13 } 14 Queue<Integer> queue = new LinkedList<>(); 15 for (int i = 0; i < n; i++) { 16 if (indegree[i] == 0) { 17 queue.offer(i); 18 } 19 } 20 while (!queue.isEmpty()) { 21 int cur = queue.poll(); 22 Set<Integer> set = adj.get(cur); 23 for (int next : set) { 24 preMap.get(next).add(cur); 25 preMap.get(next).addAll(preMap.get(cur)); 26 indegree[next]--; 27 if (indegree[next] == 0) { 28 queue.offer(next); 29 } 30 } 31 } 32 List<Boolean> res = new ArrayList<>(); 33 for (int[] pair : queries) { 34 Set<Integer> set = preMap.get(pair[1]); 35 if (set.contains(pair[0])) { 36 res.add(true); 37 } else { 38 res.add(false); 39 } 40 } 41 return res; 42 } 43 }
相关题目