[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 course 0 before you can take course 1.

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 }

 

相关题目

207. Course Schedule

210. Course Schedule II

269. Alien Dictionary

953. Verifying an Alien Dictionary

1462. Course Schedule IV

LeetCode 题目总结

posted @ 2020-09-27 09:41  CNoodle  阅读(257)  评论(0编辑  收藏  举报