Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
the-skyline-problem
Browse files Browse the repository at this point in the history
  • Loading branch information
ddaletski committed Jan 26, 2024
1 parent 2997270 commit ecb315f
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ mod three_sum_closest;
mod word_break;
mod word_search;
mod repeated_dna_sequences;
mod the_skyline_problem;
1 change: 1 addition & 0 deletions rust/src/the_skyline_problem/link.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://leetcode.com/problems/the-skyline-problem/
125 changes: 125 additions & 0 deletions rust/src/the_skyline_problem/mod.rs
Original file line number Diff line number Diff line change
@@ -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<i32>>) -> Vec<Vec<i32>> {
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::<Vec<_>>();

events.sort_by_key(|&(x, event)| (x, event.kind));

let mut result: Vec<Vec<i32>> = 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);
}
}

0 comments on commit ecb315f

Please sign in to comment.