2
// topological sort group first, then node within the group3
private List<Integer>[] groups;4
private List<Integer>[] graph;6
private int[] indegrees;8
private int[] indegreeGroups;10
public int[] sortItems(int n, int m, int[] group, List<List<Integer>> beforeItems) {11
buildGroups(n, group);12
buildGraph(n, beforeItems, group);13
int[] result = new int[n];15
Queue<Integer> queue = new LinkedList<>();16
for (int i = 0; i < n; i++) {17
if (indegreeGroups[i] == 0) {21
while (!queue.isEmpty()) {22
Integer groupId = queue.poll();23
List<Integer> groupItems = groups[groupId];24
if (groupItems == null) continue;25
Queue<Integer> itemQueue = new LinkedList<>();26
for (var item : groupItems) {27
if (indegrees[item] == 0) {28
itemQueue.offer(item);31
while (!itemQueue.isEmpty()) {32
Integer item = itemQueue.poll();34
if (graph[item] == null) continue;35
for (var neighbor : graph[item]) {36
indegrees[neighbor]--;37
if (group[neighbor] != groupId) {38
if (--indegreeGroups[group[neighbor]] == 0) {39
queue.offer(group[neighbor]);41
} else if (indegrees[neighbor] == 0) {42
itemQueue.offer(neighbor);47
if (top < n - 1) return new int[] {};51
private void buildGroups(int n, int[] group) {55
for (int i = 0; i < n; i++) {60
if (groups[group[i]] == null) {61
groups[group[i]] = new ArrayList<>();63
groups[group[i]].add(i);67
private void buildGraph(int n, List<List<Integer>> beforeItems, int[] group) {69
indegrees = new int[n];70
indegreeGroups = new int[n];71
for (int i = 0; i < n; i++) {72
for (int j : beforeItems.get(i)) {73
if (graph[j] == null) {74
graph[j] = new ArrayList<>();78
if (group[i] != group[j]) {79
indegreeGroups[group[i]]++;