1.BFS实现
public
class
Solution {
public
int
[] findOrder(
int
numCourses,
int
[][] prerequisites) {
int
[] incLinkCounts =
new
int
[numCourses];
List<List<Integer>> adjs =
new
ArrayList<>(numCourses);
initialiseGraph(incLinkCounts, adjs, prerequisites);
//return solveByBFS(incLinkCounts, adjs);
return
solveByBFS(incLinkCounts,adjs);
}
private
void
initialiseGraph(
int
[] incLinkCounts, List<List<Integer>> adjs,
int
[][] prerequisites){
int
n = incLinkCounts.length;
while
(n-- >
0
) adjs.add(
new
ArrayList<>());
for
(
int
[] edge : prerequisites) {
incLinkCounts[edge[
0
]]++;
adjs.get(edge[
1
]).add(edge[
0
]);
}
}
private
int
[] solveByBFS(
int
[] incLinkCounts, List<List<Integer>> adjs){
int
[] order =
new
int
[incLinkCounts.length];
Queue<Integer> toVisit =
new
ArrayDeque<>();
for
(
int
i =
0
; i < incLinkCounts.length; i++) {
if
(incLinkCounts[i] ==
0
) toVisit.offer(i);
}
int
visited =
0
;
while
(!toVisit.isEmpty()) {
int
from = toVisit.poll();
order[visited++] = from;
for
(
int
to : adjs.get(from)) {
incLinkCounts[to]--;
if
(incLinkCounts[to] ==
0
) toVisit.offer(to);
}
}
return
visited == incLinkCounts.length ? order :
new
int
[
0
];
}
}
2.DFS实现
public
class
Solution {
public
int
[] findOrder(
int
numCourses,
int
[][] prerequisites) {
int
[] incLinkCounts =
new
int
[numCourses];
List<List<Integer>> adjs =
new
ArrayList<>(numCourses);
initialiseGraph(incLinkCounts, adjs, prerequisites);
//return solveByBFS(incLinkCounts, adjs);
return
solveByDFS(adjs);
}
private
void
initialiseGraph(
int
[] incLinkCounts, List<List<Integer>> adjs,
int
[][] prerequisites){
int
n = incLinkCounts.length;
while
(n-- >
0
) adjs.add(
new
ArrayList<>());
for
(
int
[] edge : prerequisites) {
incLinkCounts[edge[
0
]]++;
adjs.get(edge[
1
]).add(edge[
0
]);
}
}
private
int
[] solveByBFS(
int
[] incLinkCounts, List<List<Integer>> adjs){
int
[] order =
new
int
[incLinkCounts.length];
Queue<Integer> toVisit =
new
ArrayDeque<>();
for
(
int
i =
0
; i < incLinkCounts.length; i++) {
if
(incLinkCounts[i] ==
0
) toVisit.offer(i);
}
int
visited =
0
;
while
(!toVisit.isEmpty()) {
int
from = toVisit.poll();
order[visited++] = from;
for
(
int
to : adjs.get(from)) {
incLinkCounts[to]--;
if
(incLinkCounts[to] ==
0
) toVisit.offer(to);
}
}
return
visited == incLinkCounts.length ? order :
new
int
[
0
];
}
private
int
[] solveByDFS(List<List<Integer>> adjs) {
BitSet hasCycle =
new
BitSet(
1
);
BitSet visited =
new
BitSet(adjs.size());
BitSet onStack =
new
BitSet(adjs.size());
Deque<Integer> order =
new
ArrayDeque<>();
for
(
int
i = adjs.size() -
1
; i >=
0
; i--) {
if
(visited.get(i) ==
false
&& hasOrder(i, adjs, visited, onStack, order) ==
false
)
return
new
int
[
0
];
}
int
[] orderArray =
new
int
[adjs.size()];
for
(
int
i =
0
; !order.isEmpty(); i++) orderArray[i] = order.pop();
return
orderArray;
}
private
boolean
hasOrder(
int
from, List<List<Integer>> adjs, BitSet visited, BitSet onStack, Deque<Integer> order) {
visited.set(from);
onStack.set(from);
for
(
int
to : adjs.get(from)) {
if
(visited.get(to) ==
false
) {
if
(hasOrder(to, adjs, visited, onStack, order) ==
false
)
return
false
;
}
else
if
(onStack.get(to) ==
true
) {
return
false
;
}
}
onStack.clear(from);
order.push(from);
return
true
;
}
}