From ecb315fcfb35a03ac4ad7af82d845a46af4b6fdb Mon Sep 17 00:00:00 2001 From: Denis Dalecki Date: Fri, 26 Jan 2024 18:48:25 +0100 Subject: [PATCH] the-skyline-problem --- rust/src/lib.rs | 1 + rust/src/the_skyline_problem/link.txt | 1 + rust/src/the_skyline_problem/mod.rs | 125 ++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 rust/src/the_skyline_problem/link.txt create mode 100644 rust/src/the_skyline_problem/mod.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 7bde5ec..12110ff 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -38,3 +38,4 @@ mod three_sum_closest; mod word_break; mod word_search; mod repeated_dna_sequences; +mod the_skyline_problem; diff --git a/rust/src/the_skyline_problem/link.txt b/rust/src/the_skyline_problem/link.txt new file mode 100644 index 0000000..0bf827a --- /dev/null +++ b/rust/src/the_skyline_problem/link.txt @@ -0,0 +1 @@ +https://leetcode.com/problems/the-skyline-problem/ \ No newline at end of file diff --git a/rust/src/the_skyline_problem/mod.rs b/rust/src/the_skyline_problem/mod.rs new file mode 100644 index 0000000..a812778 --- /dev/null +++ b/rust/src/the_skyline_problem/mod.rs @@ -0,0 +1,125 @@ +struct Solution; + +use std::collections::BTreeMap; + +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] +enum EventType { + Start, + End, +} + +#[derive(Clone, Copy)] +struct Event { + kind: EventType, + height: i32, +} + +impl Solution { + pub fn get_skyline(buildings: Vec>) -> Vec> { + let mut events = buildings + .into_iter() + .flat_map(|v| { + let left = v[0]; + let right = v[1]; + let height = v[2]; + + [ + ( + left, + Event { + kind: EventType::Start, + height, + }, + ), + ( + right, + Event { + kind: EventType::End, + height, + }, + ), + ] + }) + .collect::>(); + + events.sort_by_key(|&(x, event)| (x, event.kind)); + + let mut result: Vec> = vec![]; + let mut segments = BTreeMap::new(); + + for (x, Event { kind, height }) in events { + match kind { + EventType::Start => { + segments + .entry(height) + .and_modify(|count| *count += 1) + .or_insert(1); + } + EventType::End => { + if let Some(freq) = segments.get_mut(&height) { + *freq -= 1; + if *freq == 0 { + // drop(freq); + segments.remove(&height); + } + } + } + }; + + let current_max_height = segments + .last_key_value() + .map(|(k, _)| k) + .cloned() + .unwrap_or(0); + if let Some(last_entry) = result.last() { + let last_x = last_entry[0]; + let last_height = last_entry[1]; + + if last_height == current_max_height { + continue; + } else if last_x == x && last_height != current_max_height { + result.pop(); + } + } + result.push(vec![x, current_max_height]); + } + + result + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{assert_returns, vec2d}; + + #[test] + fn case1() { + let buildings = vec2d![ + [2, 9, 10], + [3, 7, 15], + [5, 12, 12], + [15, 20, 10], + [19, 24, 8] + ]; + let expected = vec2d![ + [2, 10], + [3, 15], + [7, 12], + [12, 0], + [15, 10], + [20, 8], + [24, 0] + ]; + + assert_returns!(expected, Solution::get_skyline, buildings); + } + + #[test] + fn case2() { + let buildings = vec2d![[0, 2, 3], [2, 5, 3]]; + let expected = vec2d![[0, 3], [5, 0]]; + + assert_returns!(expected, Solution::get_skyline, buildings); + } +}