思路
执行用时:180 ms, 在所有 C++ 提交中击败了30.89%的用户
内存消耗:49.9 MB, 在所有 C++ 提交中击败了68.58%的用户
[题解](🎦 1203. 项目管理 - 项目管理 - 力扣(LeetCode) (leetcode-cn.com))
这题的关键就是想到首先要给组进行拓扑排序。
时间复杂度分析
一次遍历给-1的不需要合作的项目分配组好 O ( n ) O(n) O(n)
两次建图O(n)
两次拓扑排序 O ( n + e ) O(n+e) O(n+e),遍历所有的点+边
一次合并 O ( n ) O(n) O(n)
总的时间复杂度 O ( n + e ) O(n+e) O(n+e)
大概是这样
代码
// n projects, m groups
// Firstly, projects belong to same group need to be in one group
// Secondly, projects in one group need to satisfy topological order
// In this way,the problems can be transferred to two topological problems
// How can we get topological order of groups?
// from vector group,we find that each project beglongs to a group or group[i]=-1 means project belongs to no group
// from beforeItems we get topological order of project
// so we can get topological order of groups
// How can we get topological order of items?
// directly through topological sort
// How can we get topological order in each group
// Firstly, we traverse topological items, for each item A, we get group of that item group[A];
// then we directly push_back this item to this group.
class Solution {
public:
int beforeItemsSize;
vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
beforeItemsSize = beforeItems.size();
// allocate group id to projects that belongs to no group
for (int i = 0; i < n; i++) {
if (group[i] == -1) {
group[i] = m++;
}
}
// establish graph
vector<vector<int>>groupsGraph(m);
vector<vector<int>>itemsGraph(n);
vector<int>indegreesGroups(m,0), indegreesItems(n,0);
for (int i = 0; i < n; i++) {
int& curItem = i;
int& curGroup = group[i];
for (auto& beforeItem : beforeItems[i]) {
itemsGraph[beforeItem].push_back(curItem);
indegreesItems[curItem]++;
int& beforeGroup = group[beforeItem];
if (beforeGroup == curGroup) {
continue;
}
else {
groupsGraph[beforeGroup].push_back(curGroup);
indegreesGroups[curGroup]++;
}
}
}
// topological sort
vector<int>topologicalGroups = topologicalSort(groupsGraph,indegreesGroups);
if (topologicalGroups.size() == 0) {
return vector<int>();
}
vector<int>topologicalItems = topologicalSort(itemsGraph,indegreesItems);
if (topologicalItems.size() == 0) {
return vector<int>();
}
vector<vector<int>>groups(m);
// topological sort in each group
for (int i = 0; i < n; i++) {
int& curItem = topologicalItems[i];
int curGroup = group[curItem];
groups[curGroup].push_back(curItem);
}
vector<int>res;
for (int i = 0; i < m; i++) {
int curGroup = topologicalGroups[i];
for (auto& curItem : groups[curGroup]) {
res.push_back(curItem);
}
}
return res;
}
vector<int> topologicalSort(vector<vector<int>>graphs, vector<int> indegrees) {
int n = graphs.size();
queue<int>q;
for (int i = 0; i < n; i++) {
if (indegrees[i] == 0) {
q.push(i);
}
}
int cnt = 0;
vector<int>res;
while (!q.empty()) {
int from = q.front();
q.pop();
res.push_back(from);
cnt++;
for (auto& to : graphs[from]) {
if (indegrees[to] <= 0) {
continue;
}
if (--indegrees[to] == 0) {
q.push(to);
}
}
}
if (cnt < n) {
return vector<int>();
}
return res;
}
};