课程表IV
题目:课程表 IV
你总共需要上 n 门课,课程编号依次为 0 到 n-1 。
prerequisites数对[1,0]表示1是0的先修课程。对于每个查询对 queries[i] ,请判断 queries[i][0] 是否是 queries[i][1] 的先修课程。
请返回一个布尔值列表,列表中每个元素依次分别对应 queries 每个查询对的判断结果。
示例:
输入:n = 3, prerequisites = [[1,2],[1,0],[2,0]], queries = [[1,0],[1,2]]
输出:[true,true]
题解:拓扑排序+动态规划
- 建立拓扑图
- 根据拓扑图查找拓扑排序
- 在拓扑排序中,后继节的先修课程=前继结点的所有先修课程+前继节点(动态规划)
class Solution {
public List<Boolean> checkIfPrerequisite(int numCourses, int[][] prerequisites, int[][] queries) {
Queue<Integer> queue = new ArrayDeque<>();
int indeg[] = new int[numCourses];
Map<Integer, List<Integer>> graph = new HashMap<>();
List<Boolean> res = new ArrayList<>();
Set<Integer> sequence[]=new Set[numCourses];
//建立拓扑图
for (int i = 0; i < prerequisites.length; i++) {
graph.putIfAbsent(prerequisites[i][0], new ArrayList<>());
graph.get(prerequisites[i][0]).add(prerequisites[i][1]);
indeg[prerequisites[i][1]]++;
}
//入度为0,入队列
for (int i = 0; i < indeg.length; i++) {
sequence[i]=new HashSet<>();
if (indeg[i] == 0) {
queue.add(i);
}
}
//寻找拓扑排序
while(!queue.isEmpty())
{
int temp=queue.poll();
if(graph.get(temp)!=null)
{
for (Integer next : graph.get(temp)) {
//后继节的先修课程=前继结点的所有先修课程+前继节点
sequence[next].add(temp);
sequence[next].addAll(sequence[temp]);
if(--indeg[next]==0) queue.add(next);
}
}
}
//判断queries
for(int i=0;i<queries.length;i++)
{
if(sequence[queries[i][1]].contains(queries[i][0]))
res.add(true);
else res.add(false);
}
return res;
}
}