Notes:
This question is a hard question, due to its complicated logic. It is mainly about the topological sort algorithm.
First of all, there are more than one groups. And we need to run a topological sort to all the groups, to make sure they can be arranged;
Second, inside each group, we also need to run a topological sort, to make sure that they also can be arranged in the required orders.
The topological sort is a typical algorithm, which usually requires the indgrees of each note. Firstly we will start the sort with the node having a indgree of 0 which means there is no prerequisite. During visiting or sorting, we can gradually decrease the indgree of the unvisited node when their pre-nodes are visited. Once its indegree becomes 0, it can ready to be visited.
Please check the code below:
- class Solution {
- public:
- vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
- vector<int> res;
- unordered_map<int, set<int>> gs;//group structures;
- unordered_map<int, set<int>> group_graph;//group relations
- unordered_map<int, int> group_indgree;//group indgrees;
- unordered_map<int, set<int>> memb_graph;//member relations;
- unordered_map<int, int> memb_indgree;//memeber indgree;
- int num_group = m;
- for(int i=0; i<group.size(); ++i) {
- if(group[i] == -1) {//listed as one unique group
- group[i] = num_group++;
- }
- gs[group[i]].insert(i);
- }
- for(int to=0; to<beforeItems.size(); ++to) {
- int to_group = group[to];
- for(auto &from : beforeItems[to]) {
- int from_group = group[from];
- if(from_group == to_group) {//belong to the same sub-group;
- if(!memb_graph[from].count(to)) {
- memb_graph[from].insert(to);
- ++memb_indgree[to];
- }
- }
- else {
- if(!group_graph[from_group].count(to_group)) {
- group_graph[from_group].insert(to_group);
- ++group_indgree[to_group];
- }
- }
- }
- }
- vector<int> group_res;
- queue<int> q;
- for(int i=0; i<num_group; ++i) {
- if(group_indgree[i] == 0) {
- q.push(i);
- group_res.push_back(i);
- }
- }
- while(q.size()) {
- int t = q.front();
- q.pop();
- for(auto &a : group_graph[t]) {
- if(group_indgree[a] == 0) continue;
- --group_indgree[a];
- if(group_indgree[a] == 0) {
- q.push(a);
- group_res.push_back(a);
- }
- }
- }
- if(group_res.size() != num_group) return {};
- for(auto &a : group_res) {//check each group
- int ct = 0;
- for(auto &b : gs[a]) {
- if(memb_indgree[b] == 0) {
- q.push(b);
- res.push_back(b);
- ++ct;
- }
- }
- while(q.size()) {
- auto t = q.front();
- q.pop();
- for(auto &c : memb_graph[t]) {
- if(memb_indgree[c] == 0) continue;
- --memb_indgree[c];
- if(memb_indgree[c] == 0) {
- q.push(c);
- res.push_back(c);
- ++ct;
- }
- }
- }
- if(ct != gs[a].size()) return {};
- }
- return res;
- }
- };
No comments:
Post a Comment