Skip to content

Commit ecc94a6

Browse files
authored
Create sort-items-by-groups-respecting-dependencies.cpp
1 parent c1ad6d5 commit ecc94a6

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Time: O(n + e)
2+
// Space: O(n + e)
3+
4+
class Solution {
5+
public:
6+
vector<int> sortItems(int n, int m, vector<int>& group_id, vector<vector<int>>& beforeItems) {
7+
for (int i = 0; i < n; ++i) {
8+
if (group_id[i] == -1) {
9+
group_id[i] = m++;
10+
}
11+
}
12+
Topo global_group;
13+
for (int i = 0; i < m; ++i) {
14+
global_group.addNode(i);
15+
}
16+
unordered_map<int, Topo> local_groups;
17+
for (int i = 0; i < n; ++i) {
18+
local_groups[group_id[i]].addNode(i);
19+
}
20+
for (int i = 0; i < n; ++i) {
21+
for (const auto& j : beforeItems[i]) {
22+
if (group_id[i] == group_id[j]) {
23+
local_groups[group_id[i]].addEdge(j, i);
24+
} else {
25+
global_group.addEdge(group_id[j], group_id[i]);
26+
}
27+
}
28+
}
29+
vector<int> result;
30+
const auto& global_order = global_group.sort();
31+
if (!global_order) {
32+
return {};
33+
}
34+
for (const auto& i : *global_order) {
35+
const auto& local_order = local_groups[i].sort();
36+
if (!local_order) {
37+
return {};
38+
}
39+
for (const auto& x : *local_order) {
40+
result.emplace_back(x);
41+
}
42+
}
43+
return result;
44+
}
45+
46+
private:
47+
class Topo {
48+
public:
49+
void addNode(int node) {
50+
nodes_.emplace(node);
51+
}
52+
53+
void addEdge(int from, int to) {
54+
addNode(from), addNode(to);
55+
in_degree_[to].emplace(from);
56+
out_degree_[from].emplace(to);
57+
}
58+
59+
unique_ptr<vector<int>> sort() {
60+
queue<int> q;
61+
auto result = make_unique<vector<int>>();
62+
for (const auto& node : nodes_) {
63+
if (!in_degree_.count(node)) {
64+
q.emplace(node);
65+
}
66+
}
67+
while (!q.empty()) {
68+
auto node = q.front(); q.pop();
69+
result->emplace_back(node);
70+
for (const auto& nei : out_degree_[node]) {
71+
in_degree_[nei].erase(node);
72+
if (in_degree_[nei].empty()) {
73+
in_degree_.erase(nei);
74+
q.emplace(nei);
75+
}
76+
}
77+
}
78+
if (result->size() < nodes_.size()) {
79+
return nullptr;
80+
}
81+
return result;
82+
}
83+
84+
private:
85+
unordered_set<int> nodes_;
86+
unordered_map<int, unordered_set<int>> in_degree_;
87+
unordered_map<int, unordered_set<int>> out_degree_;
88+
};
89+
};

0 commit comments

Comments
 (0)