Skip to content

Commit ad10613

Browse files
committed
LC 1942. The Number of the Smallest Unoccupied Chair (Rust)
1 parent e67552e commit ad10613

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ to the solution in this repository.
631631
| [1926. Nearest Exit from Entrance in Maze][lc1926] | 🟠 Medium | [![python](res/py.png)][lc1926py] |
632632
| [1930. Unique Length-3 Palindromic Subsequences][lc1930] | 🟠 Medium | [![rust](res/rs.png)][lc1930rs] |
633633
| [1937. Maximum Number of Points with Cost][lc1937] | 🟠 Medium | [![rust](res/rs.png)][lc1937rs] |
634+
| [1942. The Number of the Smallest Unoccupied Chair][lc1942] | 🟠 Medium | [![rust](res/rs.png)][lc1942rs] |
634635
| [1945. Sum of Digits of String After Convert][lc1945] | 🟢 Easy | [![rust](res/rs.png)][lc1945rs] |
635636
| [1962. Remove Stones to Minimize the Total][lc1962] | 🟠 Medium | [![python](res/py.png)][lc1962py] |
636637
| [1964. Find the Longest Valid Obstacle Course at Each Position][lc1964] | 🔴 Hard | [![rust](res/rs.png)][lc1964rs] |
@@ -2158,6 +2159,8 @@ to the solution in this repository.
21582159
[lc1930rs]: leetcode/unique-length-3-palindromic-subsequences.rs
21592160
[lc1937]: https://leetcode.com/problems/maximum-number-of-points-with-cost/
21602161
[lc1937rs]: leetcode/maximum-number-of-points-with-cost.rs
2162+
[lc1942]: https://leetcode.com/problems/the-number-of-the-smallest-unoccupied-chair/
2163+
[lc1942rs]: leetcode/the-number-of-the-smallest-unoccupied-chair.rs
21612164
[lc1945]: https://leetcode.com/problems/sum-of-digits-of-string-after-convert/
21622165
[lc1945rs]: leetcode/sum-of-digits-of-string-after-convert.rs
21632166
[lc1962]: https://leetcode.com/problems/remove-stones-to-minimize-the-total/
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// 1942. The Number of the Smallest Unoccupied Chair
2+
// 🟠 Medium
3+
//
4+
// https://leetcode.com/problems/the-number-of-the-smallest-unoccupied-chair/
5+
//
6+
// Tags: Array - Hash Table - Heap (Priority Queue)
7+
8+
use std::{cmp::Reverse, collections::BinaryHeap, i32};
9+
10+
struct Solution;
11+
impl Solution {
12+
/// One way to solve this is to use priority queues, one for the arrival times of the friends,
13+
/// one for the friends currently using a chair sorted by the time at which they will leave,
14+
/// and one more for the chairs that are currently free, because we want the one with the
15+
/// lowest id. When a friend arrive, first pop any friends from the departure heap that will
16+
/// have left by the time this new arrival gets to the party, and add their chairs to the free
17+
/// chairs heap. Then get the lowest id amosgst the free chairs, either from the vacated chairs
18+
/// heap or the next yet unused chair and push that into the currently here heap. When we find
19+
/// the target friend, return its chair number.
20+
///
21+
/// Time complexity: O(nlog(n)) - Sorting the arrivals, popping them from the heap, and pushing
22+
/// and popping into the departures and free chairs heaps.
23+
/// Space complexity: O(n) - The heaps, arrivals starts at size n, departures can also grow to
24+
/// size n.
25+
///
26+
/// Runtime 21 ms Beats 80%
27+
/// Memory 3.06 MB Beats 60%
28+
pub fn smallest_chair(times: Vec<Vec<i32>>, target_friend: i32) -> i32 {
29+
let mut arrivals = times
30+
.into_iter()
31+
.enumerate()
32+
.map(|(i, v)| (Reverse(v[0]), v[1], i as i32))
33+
.collect::<BinaryHeap<_>>();
34+
let mut departures: BinaryHeap<(Reverse<i32>, i32)> = BinaryHeap::new();
35+
let mut vacated_chairs: BinaryHeap<Reverse<i32>> = BinaryHeap::new();
36+
let mut next_chair = 0;
37+
while let Some((in_time, out_time, id)) = arrivals.pop() {
38+
while let Some((departure_time, vacated_chair)) = departures.peek() {
39+
if in_time.0 >= departure_time.0 {
40+
vacated_chairs.push(Reverse(*vacated_chair));
41+
departures.pop();
42+
} else {
43+
break;
44+
}
45+
}
46+
let chair;
47+
if let Some(vacated_chair) = vacated_chairs.pop() {
48+
chair = vacated_chair.0;
49+
} else {
50+
chair = next_chair;
51+
next_chair += 1;
52+
}
53+
if id == target_friend {
54+
return chair;
55+
}
56+
departures.push((Reverse(out_time), chair));
57+
}
58+
unreachable!()
59+
}
60+
}
61+
62+
// Tests.
63+
fn main() {
64+
let tests = [
65+
(vec![vec![1, 4], vec![2, 3], vec![4, 6]], 1, 1),
66+
(vec![vec![3, 10], vec![1, 5], vec![2, 6]], 0, 2),
67+
(
68+
vec![
69+
vec![33889, 98676],
70+
vec![80071, 89737],
71+
vec![44118, 52565],
72+
vec![52992, 84310],
73+
vec![78492, 88209],
74+
vec![21695, 67063],
75+
vec![84622, 95452],
76+
vec![98048, 98856],
77+
vec![98411, 99433],
78+
vec![55333, 56548],
79+
vec![65375, 88566],
80+
vec![55011, 62821],
81+
vec![48548, 48656],
82+
vec![87396, 94825],
83+
vec![55273, 81868],
84+
vec![75629, 91467],
85+
],
86+
6,
87+
2,
88+
),
89+
];
90+
println!("\n\x1b[92m» Running {} tests...\x1b[0m", tests.len());
91+
let mut success = 0;
92+
for (i, t) in tests.iter().enumerate() {
93+
let res = Solution::smallest_chair(t.0.clone(), t.1);
94+
if res == t.2 {
95+
success += 1;
96+
println!("\x1b[92m✔\x1b[95m Test {} passed!\x1b[0m", i);
97+
} else {
98+
println!(
99+
"\x1b[31mx\x1b[95m Test {} failed expected: {:?} but got {}!!\x1b[0m",
100+
i, t.2, res
101+
);
102+
}
103+
}
104+
println!();
105+
if success == tests.len() {
106+
println!("\x1b[30;42m✔ All tests passed!\x1b[0m")
107+
} else if success == 0 {
108+
println!("\x1b[31mx \x1b[41;37mAll tests failed!\x1b[0m")
109+
} else {
110+
println!(
111+
"\x1b[31mx\x1b[95m {} tests failed!\x1b[0m",
112+
tests.len() - success
113+
)
114+
}
115+
}

0 commit comments

Comments
 (0)