LC.P1462[课程表IV]

方法一:拓扑排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Solution {
public List<Boolean> checkIfPrerequisite(int n, int[][] prerequisites, int[][] queries) {
List<Integer>[] g = new List[n];
Arrays.setAll(g, k -> new ArrayList<>());
int[] in = new int[n];
for (int[] p : prerequisites) {
int a = p[0], b = p[1];
g[a].add(b);
++in[b];
}
Deque<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < n; ++i) {
if (in[i] == 0) queue.offer(i);
}
boolean[][] f = new boolean[n][n];
while (!queue.isEmpty()) {
int i = queue.poll();
for (int j : g[i]) {
f[i][j] = true;
// 若 k 是 i 的先行课程,那么 k 也是 j 的先行课程
for (int k = 0; k < n; ++k) {
f[k][j] |= f[k][i];
}
if (--in[j] == 0) queue.offer(j);
}
}
List<Boolean> ans = new ArrayList<>();
for (int[] query : queries) {
int i = query[0], j = query[1];
ans.add(f[i][j]);
}
return ans;
}
}
  • 时间复杂度:$O(n^2)$
  • 空间复杂度:$O(n^2)$

方法二:Floyd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public List<Boolean> checkIfPrerequisite(int n, int[][] prerequisites, int[][] queries) {
boolean[][] f = new boolean[n][n];
for (int[] p : prerequisites) {
int a = p[0], b = p[1];
f[a][b] = true;
}
for (int k = 0; k < n; ++k) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
f[i][j] |= f[i][k] && f[k][j];
}
}
}
List<Boolean> ans = new ArrayList<>();
for (int[] query : queries) {
int i = query[0], j = query[1];
ans.add(f[i][j]);
}
return ans;
}
}
  • 时间复杂度:$O(n^3)$
  • 空间复杂度:$O(n^2)$