题目截图
题目分析
- 没有第一个条件,就是简单topo排序
- 有了第一个条件,每个小组都需要完全隔开,因此不同小组间也需要一个topo排
- step1:对于group为-1的自成一组
- step2:建图,组内以及组间,对于beforeItems的关系,通过groupId判断是组间还是组内
- step3:topo check函数
- step4:先判断组间能否完成topo,记录inter_topo顺序
- step5:按照inter_topo再各自判断inner_topo,如果全部inner_topo都合法,合成whole_topo即可
ac code
class Solution:
def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]:
groupIndex2groupMember = defaultdict(list)
for i in range(n):
if group[i] == -1:
group[i] = m
m += 1
groupIndex2groupMember[group[i]].append(i)
inter = defaultdict(list)
inner = defaultdict(lambda: defaultdict(list))
for i in range(n):
for j in beforeItems[i]:
if group[i] == group[j]:
inner[group[i]][j].append(i)
else:
inter[group[j]].append(group[i])
def check_topo(g, nodes):
indeg = defaultdict(int)
for x in g:
for y in g[x]:
indeg[y] += 1
q = [i for i in nodes if indeg[i] == 0]
topo_ans = q[:]
while q:
new_q = []
for qq in q:
for next_node in g[qq]:
indeg[next_node] -= 1
if indeg[next_node] == 0:
topo_ans.append(next_node)
new_q.append(next_node)
q = new_q
return topo_ans if len(topo_ans) == len(nodes) else []
inter_topo = check_topo(inter, list(set(group)))
if len(inter_topo) == 0:
return []
whole_topo = []
for idx in inter_topo:
inner_topo = check_topo(inner[idx], groupIndex2groupMember[idx])
if len(inner_topo) == 0:
return []
whole_topo.extend(inner_topo)
return whole_topo
- 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
总结
- 学到了一个二维defaultdict的写法:
- inner = defaultdict(lambda: defaultdict(list))
- 组间组内topo,关键是通过同组要连续放,想到组间topo
- 然后组内topo就很自然了