1. 程式人生 > 其它 >1203. Sort Items by Groups Respecting Dependencies(Leetcode每日一題-2021.01.12)--抄答案

1203. Sort Items by Groups Respecting Dependencies(Leetcode每日一題-2021.01.12)--抄答案

技術標籤:leetcode每日一題202101leetcode拓撲排序

Problem

There are n items each belonging to zero or one of m groups where group[i] is the group that the i-th item belongs to and it’s equal to -1 if the i-th item belongs to no group. The items and the groups are zero indexed. A group can have no item belonging to it.

Return a sorted list of the items such that:

  • The items that belong to the same group are next to each other in the sorted list.
  • There are some relations between these items where beforeItems[i] is a list containing all the items that should come before the i-th item in the sorted array (to the left of the i-th item).

Return any solution if there is more than one solution and return an empty list if there is no solution.

Constraints:

  • 1 <= m <= n <= 3 * 10^4
  • group.length == beforeItems.length == n
  • -1 <= group[i] <= m - 1
  • 0 <= beforeItems[i].length <= n - 1
  • 0 <= beforeItems[i][j] <= n - 1
  • i != beforeItems[i][j]
  • beforeItems[i] does not contain duplicates elements.

Example1

在這裡插入圖片描述

Input: n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3,6],[],[],[]]
Output: [6,3,4,1,5,2,0,7]

Example2

Input: n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3],[],[4],[]]
Output: []
Explanation: This is the same as example 1 except that 4 needs to be before 6 in the sorted list.

Solution

class Solution {
public:
    vector<int> topologicalSort(vector<vector<int>> &Adj, vector<int> &Indegree, int n){
        vector<int> res;
        queue<int> q;
        for(int i = 0;i<n;i++){
            if(Indegree[i]==0){
                q.push(i);
            }
        }
        while(!q.empty()){
            int front = q.front();
            q.pop();
            res.push_back(front);
            for(int successor: Adj[front]){
                Indegree[successor]--;
                if(Indegree[successor]==0){
                    q.push(successor);
                }
            }
        }
        if(res.size()==n){return res;}
        return vector<int>();
    }
    vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
        // 第 1 步:資料預處理,給沒有歸屬於一個組的專案編上組號
        for(int i=0;i<group.size();i++){
            if(group[i] == -1){
                group[i] = m;
                m++;
            }
        }
        // 第 2 步:例項化組和專案的鄰接表
        vector<vector<int>> groupAdj(m, vector<int>());
        vector<vector<int>> itemAdj(n, vector<int>());

        // 第 3 步:建圖和統計入度陣列
        vector<int> groupsIndegree(m, 0);
        vector<int> itemIndegree(n, 0);

        int len = group.size();
        for(int i=0;i<len;i++){
            int currentGroup = group[i];
            for(int beforeItem: beforeItems[i]){
                int beforeGroup = group[beforeItem];
                if(beforeGroup!=currentGroup){
                    groupAdj[beforeGroup].push_back(currentGroup);
                    groupsIndegree[currentGroup]++;
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int item: beforeItems[i]){
                itemAdj[item].push_back(i);
                itemIndegree[i]++;
            }
        }
        // 第 4 步:得到組和專案的拓撲排序結果
        vector<int> groupList = topologicalSort(groupAdj, groupsIndegree, m);
        if(groupList.size()==0){
            return vector<int> ();
        }
        vector<int> itemList = topologicalSort(itemAdj, itemIndegree, n);
        if(itemList.size()==0){
            return vector<int> ();
        }
        // 第 5 步:根據專案的拓撲排序結果,專案到組的多對一關係,建立組到專案的一對多關係
        // key:組,value:在同一組的專案列表
        map<int, vector<int>> group2Items;
        for(int item: itemList){
            group2Items[group[item]].push_back(item);
        }
        // 第 6 步:把組的拓撲排序結果替換成為專案的拓撲排序結果
        vector<int> res;
        for(int groupId: groupList){
            vector<int> items = group2Items[groupId];
            for(int item: items){
                res.push_back(item);
            }
        }
        return res;
    } 
};