1. 程式人生 > 其它 >LeetCode 1203. 專案管理(兩次拓撲排序)

LeetCode 1203. 專案管理(兩次拓撲排序)

技術標籤:LeetCode

文章目錄

1. 題目

公司共有 n 個專案和 m 個小組,每個專案要不無人接手,要不就由 m 個小組之一負責。

group[i] 表示第 i 個專案所屬的小組,如果這個專案目前無人接手,那麼 group[i] 就等於 -1。(專案和小組都是從零開始編號的)小組可能存在沒有接手任何專案的情況。

請你幫忙按要求安排這些專案的進度,並返回排序後的專案列表:

  • 同一小組的專案,排序後在列表中彼此相鄰
  • 專案之間存在一定的依賴關係,我們用一個列表 beforeItems 來表示,其中 beforeItems[i] 表示在進行第 i 個專案前(位於第 i 個專案左側)應該完成的所有專案。

如果存在多個解決方案,只需要返回其中任意一個即可。
如果沒有合適的解決方案,就請返回一個 空列表 。

示例 1:

輸入:n = 8, m = 2, 
group = [-1,-1,1,0,0,1,0,-1], 
beforeItems = [[],[6],[5],[6],[3,6],[],[],[]]
輸出:[6,3,4,1,5,2,0,7]
示例 2:

輸入:n = 8, m = 2, 
group = [-1,-1,1,0,0,1,0,-1], 
beforeItems = [[],[6],[5],[6],[3],[],[4],[]]
輸出:[]
解釋:與示例 1 大致相同,但是在排序後的列表中,4
必須放在 6 的前面。 提示: 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] 不含重複元素

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sort-items-by-groups-respecting-dependencies

著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

2. 解題

拓撲排序學習、及相關題目

  • 兩次拓撲排序即可
class Solution {
public:
    vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
        for(int i = 0; i < n; i++)
        {
            if(group[i] == -1)
                group[i] = m++;//無人接管的分配一個虛擬團隊號
        }
        vector<vector<int>> itemgraph(n);
        vector<vector<int>> groupgraph(m);
        vector<int> itemIndegree(n, 0);
        vector<int> groupIndegree(m, 0);
        for(int i = 0; i < n; i++)
        {
            for(auto j : beforeItems[i])
            {
                itemgraph[j].push_back(i);//建圖
                itemIndegree[i]++;//記錄出入度
                if(group[i] != group[j]) // 注意條件
                {	// 團隊也建圖,記錄出入度
                    groupgraph[group[j]].push_back(group[i]);
                    groupIndegree[group[i]]++;
                }
            }
        }
        vector<vector<int>> g_items(m);
        // item 拓撲排序
        queue<int> q;
        for(int i = 0; i < n; i++)
            if(itemIndegree[i] == 0)
                q.push(i);
        int countItem = 0;
        while(!q.empty())
        {
            int i = q.front();
            q.pop();
            countItem++;
            g_items[group[i]].push_back(i);
            //每個item順序存入自己的團隊
            for(auto j : itemgraph[i])
            {
                if(--itemIndegree[j]==0)
                    q.push(j);
            }
        }
        if(countItem != n)
            return {};
        // 團隊拓撲排序
        vector<int> g_order;
        for(int i = 0; i < m; i++)
            if(groupIndegree[i] == 0)
                q.push(i);
        int countgroup = 0;
        while(!q.empty())
        {
            int g = q.front();
            q.pop();
            countgroup++;
            g_order.push_back(g);
            for(auto j : groupgraph[g])
            {
                if(--groupIndegree[j]==0)
                    q.push(j);
            }
        }
        if(countgroup != m)
            return {};
        // 寫入答案
        vector<int> ans(n);
        int idx = 0;
        for(auto g : g_order)
        {
            for(auto i : g_items[g])
                ans[idx++] = i;
        }
        return ans;
    }
};

200 ms 43 MB C++


我的CSDN部落格地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!
Michael阿明