Skip to content

Commit

Permalink
Add problem 2050: Parallel Courses III
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Aug 24, 2024
1 parent b5b1669 commit 583b89a
Show file tree
Hide file tree
Showing 4 changed files with 176 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 @@ -1515,6 +1515,7 @@ pub mod problem_2044_count_number_of_maximum_bitwise_or_subsets;
pub mod problem_2047_number_of_valid_words_in_a_sentence;
pub mod problem_2048_next_greater_numerically_balanced_number;
pub mod problem_2049_count_nodes_with_the_highest_score;
pub mod problem_2050_parallel_courses_iii;
pub mod problem_2053_kth_distinct_string_in_an_array;
pub mod problem_2054_two_best_non_overlapping_events;
pub mod problem_2055_plates_between_candles;
Expand Down
86 changes: 86 additions & 0 deletions src/problem_2050_parallel_courses_iii/iterative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
pub struct Solution;

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

use std::cell::Cell;
use std::mem;

impl Solution {
pub fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
let _ = n;
let states = time.into_iter().map(|x| Cell::new(x as u32)).collect::<Vec<_>>();
let n = states.len();
let mut graph = vec![Vec::new(); n].into_boxed_slice();

for relation in relations {
let [prev, next]: [_; 2] = relation.try_into().ok().unwrap();

graph[prev as u32 as usize - 1].push(next as u16 - 1);
}

let mut result = 0;
let mut stack = Vec::new();

for node in 0..n {
let children = &mut graph[node];
let mut state = &states[node];

if !children.is_empty() {
let mut max = 0;
let mut iter = mem::take(children).into_iter();

loop {
loop {
if let Some(child) = iter.next() {
stack.push((state, max, iter));

let node = usize::from(child);
let children = &mut graph[node];

state = &states[node];

if !children.is_empty() {
max = 0;
iter = mem::take(&mut graph[usize::from(child)]).into_iter();

continue;
}
} else {
state.set(state.get() + max);
}

break;
}

if let Some((top_state, top_max, top_iter)) = stack.pop() {
max = top_max.max(state.get());
state = top_state;
iter = top_iter;
} else {
break;
}
}
}

result = result.max(state.get());
}

result as _
}
}

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

impl super::Solution for Solution {
fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
Self::minimum_time(n, relations, time)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
25 changes: 25 additions & 0 deletions src/problem_2050_parallel_courses_iii/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub mod iterative;
pub mod recursive;

pub trait Solution {
fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32;
}

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

pub fn run<S: Solution>() {
let test_cases = [
((3, &[[1, 3], [2, 3]] as &[_], &[3, 2, 5] as &[_]), 8),
((5, &[[1, 5], [2, 5], [3, 5], [3, 4], [4, 5]], &[1, 2, 3, 4, 5]), 12),
];

for ((n, relations, time), expected) in test_cases {
assert_eq!(
S::minimum_time(n, relations.iter().map(Vec::from).collect(), time.to_vec()),
expected,
);
}
}
}
64 changes: 64 additions & 0 deletions src/problem_2050_parallel_courses_iii/recursive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
pub struct Solution;

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

use std::cell::Cell;
use std::mem;

impl Solution {
fn dfs(graph: &mut [Vec<u16>], states: &[Cell<u32>], node: u16) -> u32 {
let node = usize::from(node);
let children = &mut graph[node];
let state = &states[node];

if !children.is_empty() {
let children = mem::take(children);
let mut max = 0;

for child in children {
max = max.max(Self::dfs(graph, states, child));
}

state.set(state.get() + max);
}

state.get()
}

pub fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
let _ = n;
let states = time.into_iter().map(|x| Cell::new(x as u32)).collect::<Vec<_>>();
let n = states.len();
let mut graph = vec![Vec::new(); n].into_boxed_slice();

for relation in relations {
let [prev, next]: [_; 2] = relation.try_into().ok().unwrap();

graph[prev as u32 as usize - 1].push(next as u16 - 1);
}

let mut max = 0;

for node in 0..n as u16 {
max = max.max(Self::dfs(&mut graph, &states, node));
}

max as _
}
}

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

impl super::Solution for Solution {
fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
Self::minimum_time(n, relations, time)
}
}

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

0 comments on commit 583b89a

Please sign in to comment.