-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathSort Items by Groups Respecting Dependencies.rs
99 lines (97 loc) · 3.16 KB
/
Sort Items by Groups Respecting Dependencies.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Runtime: 35 ms (Top 22.2%) | Memory: 9.89 MB (Top 25.7%)
use std::collections::{HashMap,VecDeque};
impl Solution {
pub fn sort_items(n: i32, m: i32, group: Vec<i32>, before_items: Vec<Vec<i32>>) -> Vec<i32> {
let mut outer_graph: HashMap<i32, Vec<i32>> = HashMap::new();
let mut inner_graph: HashMap<i32, HashMap<i32, Vec<i32>>> = HashMap::new();
for i in 0..n as usize {
if group[i] == -1 && before_items[i].is_empty() {
outer_graph.entry(i as i32).or_default();
} else if group[i] == -1 {
outer_graph.entry(i as i32).or_default();
for b in &before_items[i] {
let gp = group[*b as usize];
if gp == -1 {
outer_graph.entry(*b).or_default().push(i as i32);
} else {
outer_graph.entry(gp + 40000).or_default().push(i as i32);
}
}
} else {
outer_graph.entry(group[i] + 40000).or_default();
inner_graph
.entry(group[i])
.or_default()
.entry(i as i32)
.or_default();
for b in &before_items[i] {
let gp = group[*b as usize];
if gp == -1 {
outer_graph.entry(*b).or_default().push(group[i] + 40000);
} else if group[i] == gp {
inner_graph
.entry(gp)
.or_default()
.entry(*b)
.or_default()
.push(i as i32);
} else {
outer_graph
.entry(gp + 40000)
.or_default()
.push(group[i] + 40000);
}
}
}
}
if let Some(res) = Self::topo_sort(&outer_graph, &inner_graph) {
if res.len() != n as usize {
return vec![];
}
return res;
} else {
return vec![];
}
}
fn topo_sort(
graph: &HashMap<i32, Vec<i32>>,
inner_graph: &HashMap<i32, HashMap<i32, Vec<i32>>>,
) -> Option<Vec<i32>> {
let mut res: Vec<i32> = vec![];
let mut in_degree: HashMap<i32, i32> = HashMap::new();
let mut queue: VecDeque<i32> = VecDeque::new();
for (k, v) in graph {
in_degree.entry(*k).or_default();
for n in v {
*in_degree.entry(*n).or_default() += 1;
}
}
for (k, v) in &in_degree {
if *v == 0 {
queue.push_back(*k);
}
}
while !queue.is_empty() {
let n = queue.pop_front().unwrap();
if n < 40000 {
res.push(n)
} else {
if let Some(mut s) = Self::topo_sort(&inner_graph[&(n - 40000)], inner_graph) {
if s.len() != inner_graph[&(n - 40000)].len() {
return None;
}
res.append(&mut s);
} else {
return None;
}
}
for v in &graph[&n] {
*in_degree.entry(*v).or_default() -= 1;
if in_degree[v] == 0 {
queue.push_back(*v);
}
}
}
return Some(res);
}
}