Furthest Building You Can Reach

MediumHeap · Greedy🧩 Heap & Top-KLeetCode #1642 ↗Updated

Problem

You walk from building 0 towards the right through heights. Stepping down or to an equal height is free. Climbing up by d costs either d bricks or exactly one ladder (any height). Spend your bricks and ladders optimally and return the furthest index you can reach.
Input[4,2,7,6,9,14,12], b=5, l=1Output4
Input[4,12,2,7,3,18,20,3,19], b=10, l=2Output7
Input[14,3,19,3], b=17, l=0Output3

1 ≤ n ≤ 105  ·  1 ≤ heights[i] ≤ 106  ·  0 ≤ bricks ≤ 109  ·  0 ≤ ladders ≤ n

Try it yourself

Java
class Solution {
    public int furthestBuilding(int[] heights, int bricks, int ladders) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Ladders are worth the most on the biggest climbs. Tentatively give every climb a ladder; once you have more climbs than ladders, pay bricks for the smallest one so far — a min-heap of size ladders tracks exactly that.
PatternHeap & Top-K

Instinct "K largest / smallest / closest / most frequent", or "always take the best available next"? Keep a heap - size k for top-K, or a ready-queue for scheduling.

Memory hack Guard the top-K club with a bouncer - a min-heap of size k whose root is the weakest member; anyone stronger kicks them out.

Open the Heap & Top-K guide →

Approaches

Brute ForceTry Bricks or Ladder at Every Climb

Time O(2n)Space O(n)

At each upward step branch two ways: pay with bricks (if enough) or use a ladder (if any left); steps down are free. Return the furthest index over all branches. Exhaustive, so it is correct — unlike “bricks first, ladder when short”, which wastes bricks on a big early climb.

Java
public int furthestBuilding(int[] heights, int bricks, int ladders) {
    return go(heights, 0, bricks, ladders);
}

private int go(int[] h, int i, int bricks, int ladders) {
    if (i == h.length - 1) return i;
    int diff = h[i + 1] - h[i];
    if (diff <= 0) return go(h, i + 1, bricks, ladders);
    int best = i; // stuck here if neither option works
    if (bricks >= diff) best = Math.max(best, go(h, i + 1, bricks - diff, ladders));
    if (ladders > 0) best = Math.max(best, go(h, i + 1, bricks, ladders - 1));
    return best;
}

Correct by exhaustion, but doubles with every climb.

At a glance

LevelApproachTimeSpace
Brute ForceTry Bricks or Ladder at Every ClimbO(2n)O(n)
BetterBinary Search on the AnswerO(n log2 n)O(n)
OptimalMin-Heap of Ladder ClimbsO(n log L)O(L)
Common pitfalls
  • Greedy “bricks first, ladder when short” — wastes bricks on a big climb.
  • Using a max-heap of ladder climbs — you must evict the smallest one to bricks.
  • Summing brick costs in an int — up to 1011, needs long.
Interview tips
  • Show a counter-example for the naive greedy before proposing the heap.
  • Justify with an exchange argument: swapping a ladder onto a larger climb never hurts.
  • Mention the symmetric variant: max-heap of brick climbs, swap the largest for a ladder.
Pattern
Top-k heap greedy → reserve a limited premium resource for the k largest costs seen so far.
My notes saved in this browser