题目描述:公司共有 n 个项目和 m 个小组,每个项目要不无人接手,要不就由 m 个小组之一负责。
group[i] 表示第 i 个项目所属的小组,如果这个项目目前无人接手,那么 group[i] 就等于 -1。(项目和小组都是从零开始编号的)小组可能存在没有接手任何项目的情况。
请你帮忙按要求安排这些项目的进度,并返回排序后的项目列表:
同一小组的项目,排序后在列表中彼此相邻。
项目之间存在一定的依赖关系,我们用一个列表 beforeItems 来表示,其中 beforeItems[i] 表示在进行第 i 个项目前(位于第 i 个项目左侧)应该完成的所有项目。
如果存在多个解决方案,只需要返回其中任意一个即可。如果没有合适的解决方案,就请返回一个 空列表 。
解题思路:根基beforeItems分别构建基于item和group的图,因为item有对应的group所以也可以构建基于group图,然后分别对这两个图进行拓扑排序,对拓扑排序后的项目根据group做映射,再按照group的顺序一次加入项目,代码如下:
class Solution:
def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]:
#给没有分组的重新设定分组,之所以这样做的原因是group为-1的项目即使不排在一起也可以,这和他们属于不同的组是同样的效果
for i in range(n):
if group[i] == -1:
group[i] = m
m += 1
#以项目和组别分别构建图
from collections import defaultdict
G_group = defaultdict(list)
group_indegree = [0] * m
G_item = defaultdict(list)
item_indegree = [0] * n
for i in range(n):
cur_group = group[i]
for before in beforeItems[i]:
before_group = group[before]
if before_group != cur_group:
G_group[before_group].append(cur_group)
group_indegree[cur_group] += 1
G_item[before].append(i)
item_indegree[i] += 1
from queue import Queue
def topologicalSort(indgree, G):
q = Queue()
for i in range(len(indgree)):
if indgree[i] == 0:
q.put(i)
res = []
while(q.qsize()):
cur = q.get()
res.append(cur)
for v in G[cur]:
indgree[v] -= 1
if indgree[v] == 0:
q.put(v)
if len(res) == len(indgree):
return res
return []
sort_groups = topologicalSort(group_indegree, G_group)
if len(sort_groups) == 0: return []
sort_items = topologicalSort(item_indegree, G_item)
if len(sort_items) == 0: return []
group_dict = defaultdict(list)
for i in sort_items:
group_dict[group[i]].append(i)
res = []
for g in sort_groups:
res.extend(group_dict[g])
return res