-
Notifications
You must be signed in to change notification settings - Fork 45
/
Sort_Items_by_Groups_Respecting_Dependencies.py
63 lines (52 loc) · 1.75 KB
/
Sort_Items_by_Groups_Respecting_Dependencies.py
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Sort Items by Groups Respecting Dependencies
Topological sort (twice)"""
from typing import *
class Graph:
def __init__(self, n: int):
self.n = n
self.out_edges = [[] for _ in range(n)]
self.in_degree = [0] * n
def add_edge(self, u: int, v: int):
self.out_edges[u].append(v)
self.in_degree[v] += 1
def topological_sort(self) -> List[int]:
n = self.n
in_degree = self.in_degree.copy()
out_edges = self.out_edges
queue = [i for i in range(n) if in_degree[i] == 0]
ptr = 0
while ptr < len(queue):
u = queue[ptr]
ptr += 1
for v in out_edges[u]:
in_degree[v] -= 1
if in_degree[v] == 0:
queue.append(v)
return queue
class Solution:
def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]:
# First topological sort on items
g = Graph(n)
for i in range(n):
for pre in beforeItems[i]:
g.add_edge(pre, i)
order = g.topological_sort()
if len(order) < n:
return []
# Now, topological sort on groups
for i in range(n):
if group[i] == -1:
group[i] = m
m += 1
grouped_items = [[] for i in range(m)]
for i in order:
grouped_items[group[i]].append(i)
g = Graph(m)
for i in range(n):
for pre in beforeItems[i]:
if group[pre] != group[i]:
g.add_edge(group[pre], group[i])
order = g.topological_sort()
if len(order) < m:
return []
return [item for i in order for item in grouped_items[i]]