Furthest Building You Can Reach
Problem Statement
You are given building heights in an array heights, plus bricks and ladders. Moving from building i to i + 1 costs nothing if the next building is not taller. If it is taller by climb, you must cover that climb using either climb bricks or one ladder. Return the index of the furthest building you can reach.
Input
An integer array heights, an integer bricks, and an integer ladders.
Output
An integer: the largest building index reachable from building 0.
Constraints
- •
1 <= heights.length <= 10^5 - •
1 <= heights[i] <= 10^6 - •
0 <= bricks <= 10^9 - •
0 <= ladders <= heights.length
Examples
Example 1
heights = [4,2,7,6,9,14,12], bricks = 5, ladders = 1
4Example 2
heights = [4,12,2,7,3,18,20,3,19], bricks = 10, ladders = 2
7Example 3
heights = [14,3,19,3], bricks = 17, ladders = 0
3Learning Objectives
- Identify why ladders should be saved for the largest climbs, not simply the earliest climbs.
- Use a min-heap to downgrade the smallest ladder climb to bricks when too many climbs need ladders.
- Stop exactly at the edge where brick usage first becomes negative.
- Explain the exchange argument behind assigning premium resources to largest costs.
Intuition
The greedy insight is that ladders are more valuable on larger climbs because a ladder pays one climb regardless of height. If you have seen several positive climbs and only ladders ladders, the best use of those ladders is on the largest climbs among them.
A min-heap lets us revise earlier assignments. Pretend every positive climb gets a ladder by pushing it into the heap. When the heap contains more climbs than ladders, one climb must be paid with bricks. We choose the smallest climb in the heap for bricks, leaving ladders assigned to the largest climbs seen so far.
This avoids the common trap of spending ladders as soon as possible. The heap continuously upgrades ladders to the largest climbs and downgrades smaller climbs to bricks.
Common mistakes
- ×Using a ladder on the first positive climb without considering larger climbs later.
- ×Putting every height difference in the heap, including zero or negative moves that cost nothing.
- ×Returning the next building index after bricks go negative instead of the current building index.
- ×Using a max-heap for the ladder set and accidentally paying bricks for the largest climb.
Algorithm Explanation
Greedy strategy
Use ladders for the largest positive climbs seen so far. Store ladder-assigned climbs in a min-heap. Whenever the heap size exceeds ladders, remove the smallest climb and pay for that one with bricks.
Why it works
For any prefix of climbs, suppose we must choose which climbs get ladders. Since each ladder has the same cost no matter the climb size, bricks should cover the smaller climbs and ladders should cover the larger climbs. The min-heap enforces exactly that for every prefix.
Proof of correctness
Consider any reachable prefix and any allocation that uses a ladder on a smaller climb a while using bricks on a larger climb b. Swapping the ladder from a to b decreases brick usage by b - a or leaves it unchanged if a = b. The number of ladders used is the same, and reachability cannot get worse. Repeating this exchange transforms an optimal allocation into one where ladders cover the largest climbs in the prefix. Our heap algorithm maintains that allocation after every climb by ejecting the smallest ladder climb to bricks whenever there are too many ladder candidates. Therefore, when bricks first become negative, no other allocation can reach the next building.
Algorithm
- Create a min-heap for positive climbs currently assigned to ladders.
- Iterate from building 0 to n - 2.
- Ignore non-positive climbs.
- Push each positive climb into the heap.
- If the heap size is greater than ladders, poll the smallest climb and subtract it from bricks.
- If bricks becomes negative, return the current building index.
- If the loop completes, return n - 1.
Solutions
Solution: Min-heap of ladder climbs
Maintain the set of climbs currently receiving ladders. The heap always contains the largest climbs seen so far because whenever it grows beyond the ladder count, the smallest climb is removed and paid with bricks.
Step-by-step
- Create an empty min-heap named ladderClimbs.
- For each edge between adjacent buildings, compute the positive climb.
- Push every positive climb into the heap as if it were assigned a ladder.
- If the heap now has more entries than ladders, remove the smallest climb and spend that many bricks.
- If bricks are negative after that payment, return the current index because the next building cannot be reached.
- Otherwise continue and return the last index when all moves succeed.
O(n log l)
O(l)
The heap stores at most ladders + 1 climbs, so each positive climb costs O(log l), with l representing the number of ladders plus one for overflow.
Java implementation
Dry Run
Sample input
heights = [4,2,7,6,9,14,12], bricks = 5, ladders = 1. The heap stores climbs currently reserved for ladders.
| move | climb | heap after push | brick payment | bricks left | furthest confirmed |
|---|---|---|---|---|---|
| 0 -> 1 | 0 | [] | none | 5 | 1 |
| 1 -> 2 | 5 | [5] | none | 5 | 2 |
| 2 -> 3 | 0 | [5] | none | 5 | 3 |
| 3 -> 4 | 3 | [3,5] | pay 3 | 2 | 4 |
| 4 -> 5 | 5 | [5,5] | pay 5 | -3 | 4 |
With one ladder, the heap keeps one largest climb for the ladder. At move 4 -> 5, even paying bricks for the smallest ladder candidate costs 5, making bricks negative, so index 4 is the furthest reachable building.
Interview Tips
Phrase the heap as an assignment correction tool: every positive climb is a candidate for a ladder, but only the largest candidates keep ladders. When asked why the smallest heap item becomes bricks, use the premium-resource exchange: if a ladder is on a smaller climb while bricks pay a larger one, swapping them only helps.
Likely follow-ups
- How would you solve it with a max-heap that spends bricks first and refunds the largest climb when a ladder is needed?
- How would the answer change if ladders had different maximum heights?
- Can you return which climbs used ladders in addition to the furthest index?
- What if bricks could be replenished at certain buildings?
Similar Problems
Key Takeaways
- Use premium resources on the largest costs in the current prefix.
- A min-heap of ladder climbs makes the smallest ladder assignment easy to downgrade to bricks.
- When bricks first go negative, no exchange can make that prefix feasible.
- Ignoring non-positive climbs is essential because they consume no resources.