Skip to content

Commit

Permalink
Add problem 1776: Car Fleet II
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Feb 17, 2024
1 parent 32068a9 commit ff15bdf
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,7 @@ pub mod problem_1771_maximize_palindrome_length_from_subsequences;
pub mod problem_1773_count_items_matching_a_rule;
pub mod problem_1774_closest_dessert_cost;
pub mod problem_1775_equal_sum_arrays_with_minimum_number_of_operations;
pub mod problem_1776_car_fleet_ii;
pub mod problem_1779_find_nearest_point_that_has_the_same_x_or_y_coordinate;
pub mod problem_1780_check_if_number_is_a_sum_of_powers_of_three;
pub mod problem_1781_sum_of_beauty_of_all_substrings;
Expand Down
24 changes: 24 additions & 0 deletions src/problem_1776_car_fleet_ii/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pub mod monotonic_stack;

pub trait Solution {
fn get_collision_times(cars: Vec<Vec<i32>>) -> Vec<f64>;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
(
&[[1, 2], [2, 1], [4, 3], [7, 2]] as &[_],
&[1.0, -1.0, 3.0, -1.0] as &[_],
),
(&[[3, 4], [5, 4], [6, 3], [9, 1]], &[2.0, 1.0, 1.5, -1.0]),
];

for (cars, expected) in test_cases {
assert_eq!(S::get_collision_times(cars.iter().map(Vec::from).collect()), expected);
}
}
}
58 changes: 58 additions & 0 deletions src/problem_1776_car_fleet_ii/monotonic_stack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

// See <https://leetcode.com/problems/car-fleet-ii/discuss/1085987/JavaC%2B%2BPython-O(n)-Stack-Solution>.

use std::convert::TryInto;

impl Solution {
pub fn get_collision_times(cars: Vec<Vec<i32>>) -> Vec<f64> {
let mut result = vec![-1.0; cars.len()];
let mut stack = Vec::<(u32, u32, u32, u32)>::new();

for (target, car) in result.iter_mut().zip(cars).rev() {
let [position, speed]: [_; 2] = car.try_into().ok().unwrap();
let (position, speed) = (position as u32, speed as u32);

let (distance, speed_diff) = loop {
if let Some(&(right_position, right_speed, numerator, denominator)) = stack.last() {
if speed > right_speed {
let distance = right_position - position;
let speed_diff = speed - right_speed;

if u64::from(distance) * u64::from(denominator) < u64::from(numerator) * u64::from(speed_diff) {
*target = f64::from(distance) / f64::from(speed_diff);

break (distance, speed_diff);
}
}

stack.pop();
} else {
break (u32::MAX, 0);
}
};

stack.push((position, speed, distance, speed_diff));
}

result
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn get_collision_times(cars: Vec<Vec<i32>>) -> Vec<f64> {
Self::get_collision_times(cars)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}

0 comments on commit ff15bdf

Please sign in to comment.