1 minute read

1203. Sort Items by Groups Respecting Dependencies

i try to use a indegree and some graph theories but failed

class Solution:
    def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]:
        d = defaultdict(list)
        indegree = [0] * n
        req = []

        for i in range(n):
            d[group[i]].append(i)
            for item in beforeItems[i]:
                indegree[item] += 1
            req.append(set(beforeItems[i]))
        
        for key in range(-1, m):
            d[key] = sorted(d[key], key=lambda x: -indegree[x])
        
        print(d)
        print(indegree)
        print(req)
        
        res = []
        cur = set()
        while len(res) < n:
            print(d)
            print(res)
            print(cur)
            group_id = -1
            for key in d.keys():
                cur_ = set(cur)
                temp = True
                for value in d[key]:
                    if req[value] - cur_:
                        temp = False
                        break
                    cur_.add(value)
                if temp:
                    group_id = key
                    cur = cur_
                    break

            res += d[group_id]
            del d[group_id]
            
            temp = []
            for value in d[-1]:
                if req[value] - cur:
                    temp.append(value)
                else:
                    res.append(value)
                    cur.add(value)
            if temp:
                d[-1] = temp
            else:
                del d[-1]


        return res

indgree로 접근하는 방식은 좋았으나, code의 구조적인 문제.

import collections
from typing import List
class Solution:
    def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]:


        def topoSort(nodes, graph, in_degree):
            queue = collections.deque([node for node in nodes if node not in in_degree])
            ans = []

            while queue:
                cur_node = queue.popleft()
                ans.append(cur_node)

                for neighbor in graph[cur_node]:
                    in_degree[neighbor] -= 1

                    if in_degree[neighbor] == 0:
                        queue.append(neighbor)

            return ans

        group_items = defaultdict(list)
        groupId = m
        for i in range(n):
            if group[i] == -1:
                group[i] = groupId
                # no groups -> set independent groupId
                groupId += 1

            group_items[group[i]].append(i)

        item_graph = defaultdict(list)
        item_indegree = defaultdict(int)

        
        for v, u_list in enumerate(beforeItems):
            for u in u_list:
                # get indegree of items that has same groupId
                if group[u] == group[v]:
                    item_graph[u].append(v)
                    item_indegree[v] += 1


        sorted_group_items = {}
        for groupId in group_items:
            # sort items within groups
            sorted_items = topoSort(group_items[groupId], item_graph, item_indegree)

            # possibility check!
            if len(sorted_items) != len(group_items[groupId]):
                return []

            sorted_group_items[groupId] = sorted_items


        group_graph = defaultdict(list)
        group_indegree = defaultdict(int)

        for v, u_list in enumerate(beforeItems):
            for u in u_list:
                if group[u] != group[v]:
                    group_graph[group[u]].append(group[v])
                    group_indegree[group[v]] += 1


        # 아하 이해함.
        groups = set(group)
        sorted_groups = topoSort(groups, group_graph, group_indegree)

        if len(groups) != len(sorted_groups):
            return []

        ans = []
        for groupId in sorted_groups:
            ans.extend(sorted_group_items[groupId])

        return ans