Skip to content

Commit 79ea021

Browse files
committed
LeetCode 2127. Maximum Employees to Be Invited to a Meeting (Rust DFS)
1 parent d424e40 commit 79ea021

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
432432
| [2013. Detect Squares][lc2013] | 🟠 Medium | [![python](res/py.png)][lc2013py] |
433433
| [2095. Delete the Middle Node of a Linked List][lc2095] | 🟠 Medium | [![python](res/py.png)][lc2095py] |
434434
| [2115. Find All Possible Recipes from Given Supplies][lc2115] | 🟠 Medium | [![python](res/py.png)][lc2115py] |
435+
| [2127. Maximum Employees to Be Invited to a Meeting][lc2127] | 🔴 Hard | [![rust](res/rs.png)][lc2127rs] |
435436
| [2130. Maximum Twin Sum of a Linked List][lc2130] | 🟠 Medium | [![python](res/py.png)][lc2130py] |
436437
| [2131. Longest Palindrome by Concatenating Two Letter Words][lc2131] | 🟠 Medium | [![python](res/py.png)][lc2131py] |
437438
| [2136. Earliest Possible Day of Full Bloom][lc2136] | 🔴 Hard | [![python](res/py.png)][lc2136py] |
@@ -1363,6 +1364,8 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
13631364
[lc2095py]: leetcode/delete-the-middle-node-of-a-linked-list.py
13641365
[lc2115]: https://leetcode.com/problems/find-all-possible-recipes-from-given-supplies/
13651366
[lc2115py]: leetcode/find-all-possible-recipes-from-given-supplies.py
1367+
[lc2127]: https://leetcode.com/problems/maximum-employees-to-be-invited-to-a-meeting/
1368+
[lc2127rs]: leetcode/maximum-employees-to-be-invited-to-a-meeting.rs
13661369
[lc2130]: https://leetcode.com/problems/maximum-twin-sum-of-a-linked-list/
13671370
[lc2130py]: leetcode/maximum-twin-sum-of-a-linked-list.py
13681371
[lc2131]: https://leetcode.com/problems/longest-palindrome-by-concatenating-two-letter-words/
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// 2127. Maximum Employees to Be Invited to a Meeting
2+
// 🔴 Hard
3+
//
4+
// https://leetcode.com/problems/maximum-employees-to-be-invited-to-a-meeting/
5+
//
6+
// Tags: Depth-First Search - Graph - Topological Sort
7+
8+
use std::collections::{HashMap, HashSet};
9+
10+
struct Solution;
11+
impl Solution {
12+
/// There is two ways to arrange people, use the longest cycle or start on
13+
/// all pairs of people that like each other, append the longest chains of
14+
/// people at both ends starting from them. Returns the one that lets us
15+
/// sit more people.
16+
///
17+
/// Time complexity: O(n) - Both functions run in linear time.
18+
/// Space complexity: O(n) - Both functions use a linear amount of space.
19+
///
20+
/// Runtime 91 ms Beats 66.67%
21+
/// Memory 15.2 MB Beats 66.67%
22+
pub fn maximum_invitations(favorite: Vec<i32>) -> i32 {
23+
// The result is the best option between arranging the employees in
24+
// a circle vs pairs plus people that like them next to them.
25+
Solution::maximum_invitations_as_cycle(&favorite)
26+
.max(Solution::maximum_invitations_pairs(&favorite))
27+
}
28+
/// A function that computes the maximum number of people that we can invite
29+
/// when they form don't form a cycle, i.e. two people "like" each other.
30+
///
31+
/// Time O(n) - Space O(n)
32+
pub fn maximum_invitations_pairs(favorite: &Vec<i32>) -> i32 {
33+
let n = favorite.len();
34+
// Find all the pairs that like each other.
35+
let mut pairs = HashSet::<usize>::new();
36+
// A hashmap of people liked by others.
37+
let mut liked_by = vec![vec![]; n];
38+
for i in 0..n {
39+
// Skip the second elements of pairs.
40+
if pairs.contains(&i) {
41+
continue;
42+
}
43+
if (favorite[favorite[i] as usize]) as usize == i {
44+
pairs.insert(i);
45+
pairs.insert(favorite[i] as usize);
46+
} else {
47+
// A hashmap of all employees that like i and are not part of a
48+
// reciprocal pair.
49+
liked_by[favorite[i] as usize].push(i);
50+
}
51+
}
52+
// The number of people we can invite this way is the pairs plus anyone
53+
// that likes one of the people in the pair because they can seat next
54+
// to them.
55+
let mut invitees = pairs.len();
56+
for i in pairs {
57+
invitees += Solution::maximum_likes_chain(i, &liked_by);
58+
}
59+
invitees as i32
60+
}
61+
62+
/// A helper function that computes the longest chain of people that likes
63+
/// "liked". This function expects the liked_by vector to not contain the
64+
/// partner of liked if this one is part of a reciprocal pair.
65+
pub fn maximum_likes_chain(liked: usize, liked_by: &Vec<Vec<usize>>) -> usize {
66+
let mut length = 0;
67+
for i in liked_by[liked].iter() {
68+
length = length.max(Solution::maximum_likes_chain(*i, liked_by) + 1);
69+
}
70+
length
71+
}
72+
73+
/// A function that computes the maximum number of people that we can invite
74+
/// when they form a cycle, i.e. there are not reciprocal pairs.
75+
///
76+
/// Time O(n) - Space O(n)
77+
pub fn maximum_invitations_as_cycle(favorite: &Vec<i32>) -> i32 {
78+
let n = favorite.len();
79+
let mut visited = vec![false; n];
80+
let mut res = 0;
81+
// A function that explores a path starting at a given node.
82+
fn dfs(
83+
node: usize,
84+
pos: usize,
85+
visited: &mut Vec<bool>,
86+
path: &mut HashMap<usize, usize>,
87+
favorites: &Vec<i32>,
88+
) -> usize {
89+
if path.contains_key(&node) {
90+
return pos - path.get(&node).unwrap();
91+
}
92+
if visited[node] {
93+
return 0;
94+
}
95+
path.insert(node, pos);
96+
visited[node] = true;
97+
if favorites[node] != -1 {
98+
return dfs(favorites[node] as usize, pos + 1, visited, path, favorites);
99+
}
100+
0
101+
}
102+
let mut path: HashMap<usize, usize>;
103+
for employee in favorite.iter() {
104+
let i = *employee as usize;
105+
if !visited[i] {
106+
path = HashMap::new();
107+
res = res.max(dfs(i, 0, &mut visited, &mut path, &favorite));
108+
}
109+
}
110+
res as i32
111+
}
112+
}
113+
114+
// Tests.
115+
fn main() {
116+
let tests = [
117+
(vec![1, 0, 0, 2, 1, 4, 7, 8, 9, 6, 7, 10, 8], 6),
118+
(vec![1, 2, 0], 3),
119+
(vec![2, 2, 1, 2], 3),
120+
(vec![3, 0, 1, 4, 1], 4),
121+
];
122+
for t in tests {
123+
assert_eq!(Solution::maximum_invitations(t.0), t.1);
124+
}
125+
println!("All tests passed!")
126+
}

0 commit comments

Comments
 (0)