LeetCode-1203. Gestión de proyectos

descripción

La empresa tiene n proyectos y m equipos, y cada proyecto no es asumido por nadie o uno de los m equipos es responsable.

el grupo [i] representa el grupo al que pertenece el i-ésimo proyecto. Si nadie se hace cargo actualmente de este proyecto, el grupo [i] es igual a -1. (Los proyectos y equipos están numerados desde cero) El equipo no puede hacerse cargo de ningún proyecto.

Ayude a organizar el progreso de estos proyectos según sea necesario y vuelva a la lista ordenada de proyectos:

Los proyectos del mismo grupo están uno al lado del otro en la lista después de la clasificación.
Existen ciertas dependencias entre elementos, usamos una lista beforeItems para representar, donde beforeItems [i] representa todos los elementos que deben completarse antes del i-ésimo elemento (ubicado a la izquierda del i-ésimo elemento).
Si hay varias soluciones, devuelva cualquiera de ellas. Si no hay una solución adecuada, devuelva una lista vacía.

 

Ejemplo 1:

Entrada: n = 8, m = 2, grupo = [-1, -1,1,0,0,1,0, -1], beforeItems = [[], [6], [5], [6] , [3,6], [], [], []]
Resultado: [6,3,4,1,5,2,0,7]
Ejemplo 2:

Entrada: n = 8, m = 2, grupo = [-1, -1,1,0,0,1,0, -1], beforeItems = [[], [6], [5], [6] , [3], [], [4], []]
Salida: []
Explicación: Es aproximadamente lo mismo que en el ejemplo 1, pero en la lista ordenada, 4 debe colocarse delante de 6.
 

rápido:

1 <= m <= n <= 3 * 104
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] 不含 重复 元素

Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/sort-items-by-groups-respecting-dependencies/
 

Resolver (no lo hice yo mismo, consulte la solución oficial del problema https://leetcode-cn.com/problems/sort-items-by-groups-respecting-dependencies/solution/xiang-mu-guan-li -por-leetcode- solución-3e7j / )

    class Solution {
    public:
        // 两次拓扑排序
        vector<int> sortItems(int n, int m, vector<int> &group, vector<vector<int>> &beforeItems) {
            // 组的顶点入度和图
            vector<int> groupInDegree(n + m, 0); // 记录顶点的入度
            vector<vector<int>> groupGraph(n + m, vector<int>()); // 图,邻接表存储

            // 点的顶点入度和图
            vector<int> itemInDegree(n + m, 0); // 记录顶点的入度
            vector<vector<int>> itemGraph(n + m, vector<int>()); // 图,邻接表存储

            // 数据预处理,给不属于任何项目组的项目编一个唯一号
            std::unordered_map<int, vector<int>> groupItemsMap; // 每个项目组下面的项目集合
            int groupId = m;
            for (int i = 0; i < n; ++i) {
                if (group[i] == -1) {
                    // 给不属于任何项目组的项目编一个唯一号
                    group[i] = groupId++;
                }
                groupItemsMap[group[i]].emplace_back(i);
            }

            // 项目组,项目组内项目图数据构造
            for (int i = 0; i < n; ++i) {
                int curGroupId = group[i];
                for (auto item : beforeItems[i]) {
                    int beforeGroupId = group[item];
                    if (curGroupId == beforeGroupId) {
                        // 前驱项目和当前项目是属于同一项目组,则不进行组的图数据构造,否则可能形成环
                        // 进行同组内的项目图数据构造,注意,一定要是同组内的项目才进行图数据构造
                        itemGraph[item].emplace_back(i);
                        ++itemInDegree[i];
                    } else {
                        // 前驱项目和当前项目不属于同一个项目组
                        groupGraph[beforeGroupId].emplace_back(curGroupId);
                        ++groupInDegree[curGroupId];
                    }
                }
            }

            // 对项目组进行拓扑排序
            vector<int> id;
            for (int i = 0; i < n + m; ++i) {
                id.emplace_back(i);
            }
            auto groupSortRes = topSort(groupGraph, groupInDegree, id);
            if (groupInDegree.empty()) {
                return vector<int>();
            }

            // 按照项目组的拓扑排序,对每个项目组内的所有项目进行拓扑排序
            vector<int> res;
            for (auto g : groupSortRes) {
                // 项目组内无项目,不进行排序
                if (groupItemsMap[g].empty()) {
                    continue;
                }

                auto itemSortRes = topSort(itemGraph, itemInDegree, groupItemsMap[g]);
                if (itemSortRes.empty()) {
                    // 项目组内无项目,不进行排序
                    return vector<int>();
                }
                // 调用区间成员函数将项目组内项目拓扑排序结果插入最终结果
                res.insert(res.end(), itemSortRes.cbegin(), itemSortRes.cend());
            }
            return res;
        }

    private:
        /*!
*
* @param graph 图,邻接表
* @param inDegree 顶点入度
* @param items 待排序顶点
* @return  拓扑排序结果
*/
        vector<int>
        topSort(const vector<vector<int>> &graph, vector<int> &inDegree, const vector<int> &items) {
            // 找出入度为0的点开始遍历
            std::stack<int> s;
            for (auto i : items) {
                if (inDegree[i] == 0) {
                    s.push(i); // 顶点入度为0,入栈
                }
            }

            // 拓扑排序
            vector<int> res;
            while (!s.empty()) {
                int v = s.top();
                res.emplace_back(v); // 保存拓扑排序结果
                s.pop();
                for (auto w  : graph[v]) {
                    if (--inDegree[w] == 0) {
                        s.push(w);
                    }
                }
            }

            // 满足拓扑排序返回排序结果,否则返回空数组
            return res.size() == items.size() ? res : vector<int>();
        }
    };

 

Supongo que te gusta

Origin blog.csdn.net/u010323563/article/details/112548211
Recomendado
Clasificación