package com.heu.wsq.leetcode.graph;
import java.util.*;
public class SortItems {
public int[] sortItems(int n, int m, int[] group, List<List<Integer>> beforeItems) {
int totalM = m;
for (int i = 0; i < group.length; i++){
if (group[i] == -1){
group[i] = totalM;
totalM++;
}
}
List<Integer>[] groupAdj = new ArrayList[totalM];
List<Integer>[] itemAdj = new ArrayList[n];
for (int i = 0; i < totalM; i++) {
groupAdj[i] = new ArrayList<>();
}
for (int i = 0; i < n; i++){
itemAdj[i] = new ArrayList<>();
}
int[] groupsIndegree = new int[totalM];
int[] itemsIndegree = new int[n];
int len = group.length;
for (int i = 0; i < len; i++){
int currGroup = group[i];
List<Integer> befores = beforeItems.get(i);
for (Integer before : befores) {
int beforeGroup = group[before];
if (beforeGroup == currGroup){
itemsIndegree[i]++;
itemAdj[before].add(i);
}else{
groupsIndegree[currGroup]++;
groupAdj[beforeGroup].add(currGroup);
}
}
}
List<Integer> groupList = topoSort(groupAdj, groupsIndegree, totalM);
if (groupList.isEmpty()){
return new int[0];
}
List<Integer> itemList = topoSort(itemAdj, itemsIndegree, n);
if (itemList.isEmpty()){
return new int[0];
}
Map<Integer, List<Integer>> group2Items = new HashMap<>();
for (Integer item : itemList) {
group2Items.computeIfAbsent(group[item], key -> new ArrayList<>()).add(item);
}
List<Integer> res = new ArrayList<>();
for (Integer gp : groupList) {
List<Integer> items = group2Items.getOrDefault(gp, new ArrayList<>());
res.addAll(items);
}
return res.stream().mapToInt(Integer::valueOf).toArray();
}
private List<Integer> topoSort(List<Integer>[] adj, int[] indegree, int n) {
List<Integer> res = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++){
if (indegree[i] == 0){
queue.offer(i);
}
}
while (!queue.isEmpty()){
Integer front = queue.poll();
res.add(front);
for (Integer successor : adj[front]) {
indegree[successor]--;
if (indegree[successor] == 0){
queue.offer(successor);
}
}
if (res.size() == n){
return res;
}
}
return new ArrayList<>();
}
}