Skip to content

Commit 64e36e4

Browse files
committed
Added Furthest Building You Can Reach
1 parent 50a0b7e commit 64e36e4

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/// You are given an integer array `heights` representing the heights of
2+
/// buildings, some `bricks`, and some `ladders`.
3+
///
4+
/// You start your journey from building `0` and move to the next building by
5+
/// possibly using bricks or ladders.
6+
///
7+
/// While moving from building `i` to building `i+1` (0-indexed),
8+
///
9+
/// * If the current building's height is greater than or equal to the next
10+
/// building's height, you do not need a ladder or bricks.
11+
///
12+
/// * If the current building's height is less than the next building's height,
13+
/// you can either use one ladder or `(h[i+1] - h[i])` bricks.
14+
///
15+
/// Return the furthest building index (0-indexed) you can reach if you use the
16+
/// given ladders and bricks optimally.
17+
struct Solution;
18+
19+
impl Solution {
20+
21+
fn prefix_diff(n: usize, heights: &Vec<i32>) -> Vec<i32> {
22+
let mut result = Vec::new();
23+
let mut previous = heights[0];
24+
for i in 1..n {
25+
let current = heights[i];
26+
let diff = current - previous;
27+
if diff > 0 {
28+
result.push(diff);
29+
}
30+
previous = current;
31+
}
32+
result
33+
}
34+
35+
fn bricks_for_buildings(heights: &Vec<i32>, bricks: i32) -> i32 {
36+
let mut bricks = bricks;
37+
let mut result = 0;
38+
39+
for height in heights {
40+
if bricks >= *height {
41+
bricks -= height;
42+
result += 1;
43+
} else { break; }
44+
}
45+
46+
result
47+
}
48+
49+
fn check_furthest(n: usize, heights: &Vec<i32>, bricks: i32, ladders: i32) -> bool {
50+
let mut diffs = Self::prefix_diff(n, heights);
51+
diffs.sort();
52+
let brick_buildings = Self::bricks_for_buildings(&diffs, bricks);
53+
let total = brick_buildings + ladders;
54+
total >= diffs.len() as i32
55+
}
56+
57+
pub fn furthest_building(heights: Vec<i32>, bricks: i32, ladders: i32) -> i32 {
58+
let n = heights.len();
59+
let result: i32;
60+
61+
if Self::check_furthest(n, &heights, bricks, ladders) {
62+
result = n as i32;
63+
} else {
64+
let mut last_bad = n;
65+
let mut last_good = 1;
66+
67+
while last_bad - last_good > 1 {
68+
let mid = last_good + (last_bad - last_good) / 2;
69+
if Self::check_furthest(mid, &heights, bricks, ladders) {
70+
last_good = mid;
71+
} else {
72+
last_bad = mid;
73+
}
74+
}
75+
result = last_good as i32;
76+
}
77+
78+
result - 1
79+
}
80+
81+
}
82+
83+
#[cfg(test)]
84+
mod tests {
85+
use super::Solution;
86+
87+
#[test]
88+
fn example_1() {
89+
let heights = vec![4,2,7,6,9,14,12];
90+
let bricks = 5;
91+
let ladders = 1;
92+
let result = Solution::furthest_building(heights, bricks, ladders);
93+
assert_eq!(result, 4);
94+
}
95+
96+
#[test]
97+
fn example_2() {
98+
let heights = vec![4,12,2,7,3,18,20,3,19];
99+
let bricks = 10;
100+
let ladders = 2;
101+
let result = Solution::furthest_building(heights, bricks, ladders);
102+
assert_eq!(result, 7);
103+
}
104+
105+
#[test]
106+
fn example_3() {
107+
let heights = vec![14,3,19,3];
108+
let bricks = 17;
109+
let ladders = 0;
110+
let result = Solution::furthest_building(heights, bricks, ladders);
111+
assert_eq!(result, 3);
112+
}
113+
114+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ pub mod make_the_string_great; // 1544
202202

203203
pub mod minimum_number_of_vertices_to_reach_all_nodes; // 1557
204204

205+
pub mod furthest_building_you_can_reach; // 1642
206+
205207
pub mod richest_customer_wealth; // 1672
206208

207209
pub mod maximum_population_year; // 1854

0 commit comments

Comments
 (0)