Knowledge Guide
HomeDSACompany Practice

medium Furthest Building You Can Reach

Problem Statement

You are given an array of integers heights, where heights[i] is the height of the ith building, integer bricks, and integer ladders.

You start traveling from the first building and move to the next building by either using bricks or ladders.

Each time you encounter a building taller than the one you're currently on, you have two options:

Return the index (0-indexed) of the furthest building you can reach if you use the given ladders and bricks optimally.

Examples

Example 1:

Example 2:

Example 3:

Try it yourself

Try solving this question here:

✅ Solution Furthest Building You Can Reach

Problem Statement

You are given an array of integers heights, where heights[i] is the height of the ith building, integer bricks, and integer ladders.

You start traveling from the first building and move to the next building by either using bricks or ladders.

Each time you encounter a building taller than the one you're currently on, you have two options:

  • climb up using a fixed amount of bricks for each unit of height difference
  • Or, utilize a ladder to bypass the height difference entirely

Return the index (0-indexed) of the furthest building you can reach if you use the given ladders and bricks optimally.

Examples

Example 1:

  • Input: heights = [4,12,2,7,3,18,20,3,19], bricks = 10, ladders = 2
  • Expected Output: 7
  • Justification:
    • Move from building 0 to 1 using a ladder.
    • Move from building 1 to 2 without using any resources.
    • Move from building 2 to 3 using 5 bricks.
    • Move from building 3 to 4 without using any resources.
    • Move from building 4 to 5 using a ladder.
    • Move from building 5 to 6 using 2 bricks.
    • Move from building 3 to 4 without using any resources.

Example 2:

  • Input: heights = [1,5,1,2,3,4,10000], bricks = 4, ladders = 1
  • Expected Output: 5
  • Justification: Use the ladder for the large jump from 0 to 1. Use bricks for smaller climbs from 1 to 2, 2 to 3, 3 to 4, and 4 to 5. This strategy gets you to the 5th building before running out of resources.

Example 3:

  • Input: heights = [5,1,1,1,1,1,1,1,1,1,20], bricks = 10, ladders = 1
  • Expected Output: 10
  • Justification: Use the ladder for the last large climb from 9 to 10 buildings. Bricks can be used for one of the single-unit climbs if necessary, allowing you to reach the last building.

Solution

To solve this problem, we will adopt a greedy strategy that prioritizes the use of ladders for the largest height differences between buildings, ensuring bricks are conserved for smaller gaps. This approach works because ladders can cover any height difference, making them more valuable for larger gaps, whereas bricks are finite and should be used sparingly. We'll manage this by keeping track of the height differences where ladders are used in a min-priority queue structure. When we run out of ladders, we will start replacing the smallest ladder-used gaps with bricks, ensuring we always make the optimal choice for ladder and brick usage.

Our method ensures that we can travel the maximum distance by optimally utilizing the resources at our disposal. It strikes a balance between the use of ladders for significant height differences and bricks for smaller ones. This way, we stretch the utility of our resources and ensure that we can cover as much ground as possible.

Step-by-Step Algorithm

  1. Initialize a priority queue (min heap) ladderAllocations to keep track of the heights differences that have been climbed using ladders. Also, prepare a variable usedBricks to count the number of bricks used.
  2. Iterate through the array of building heights.
    • For each pair of adjacent buildings, calculate the height difference diff (if the next building is taller).
    • If diff > 0, attempt to use a ladder by adding diff to ladderAllocations.
    • If the size of ladderAllocations exceeds the number of ladders available, remove the smallest height difference from the priority queue and subtract that value from bricks.
    • If bricks value is less than 0 at any point, return the current index as the furthest building you can reach.
  3. If you can iterate through all buildings without exceeding the available bricks, return the last building's index as the furthest you can reach.

Algorithm Walkthrough

Let's consider the Input: heights = [4,12,2,7,3,18,20,3,19], bricks = 10, and ladders = 2.

  • Start with an empty priority queue and 0 used bricks.
  • Move from building 0 to 1 (heights[0] to heights[1]):
    • Height difference is 12 - 4 = 8. Since it's positive, we consider using resources.
    • Add 8 to the priority queue. Priority queue now contains [8].
    • No need to use bricks since the number of ladders exceeds the queue's size.
  • Move from building 1 to 2 (heights[1] to heights[2]):
    • Height difference is 2 - 12 = -10. No resources are needed as the next building is shorter.
  • Move from building 2 to 3 (heights[2] to heights[3]):
    • Height difference is 7 - 2 = 5. Since it's positive, we consider using resources.
    • Add 5 to the priority queue. Priority queue now contains [5, 8].
    • No need to use bricks since the number of ladders exceeds the queue's size.
  • Move from building 3 to 4 (heights[3] to heights[4]):
    • Height difference is 3 - 7 = -4. No resources are needed as the next building is shorter.
  • Move from building 4 to 5 (heights[4] to heights[5]):
    • Height difference is 18 - 3 = 15. Since it's positive, we consider using resources.
    • Add 15 to the priority queue. Priority queue now contains [5, 8, 15].
    • Since the queue's size now exceeds the number of ladders, remove the smallest element (5) and subtract from bricks. bricks becomes 5. Priority queue now contains [8, 15].
  • Move from building 5 to 6 (heights[5] to heights[6]):
    • Height difference is 20 - 18 = 2. Since it's positive, we consider using resources.
    • Add 2 to the priority queue. Priority queue now contains [2, 8, 15].
    • Since the queue's size exceeds the number of ladders, remove the smallest element (2) and subtract from bricks``. bricksbecomes3. Priority queue now contains [8, 15]`.
  • Move from building 6 to 7 (heights[6] to heights[7]):
    • Height difference is 3 - 20 = -17. No resources are needed as the next building is shorter.
  • Move from building 7 to 8 (heights[7] to heights[8]):
    • Height difference is 19 - 3 = 16. Since it's positive, we consider using resources.
    • Add 16 to the priority queue. Priority queue now contains [8, 15, 16].
    • Since the queue's size exceeds the number of ladders, remove the smallest element (8) and subtract from bricks. bricks becomes -5, which is less than 0. So, return the current index 7.
  • Final Result: You can reach to the 7th (0-based) building using the given resources.
java
import java.util.PriorityQueue;

public class Solution {

  // Determines the furthest building you can reach
  public int furthestBuilding(int[] heights, int bricks, int ladders) {
    PriorityQueue<Integer> ladderAllocations = new PriorityQueue<>();

    for (int i = 0; i < heights.length - 1; i++) {
      int diff = heights[i + 1] - heights[i];
      // Use resources if next building is higher
      if (diff > 0) {
        ladderAllocations.add(diff);
        // Use ladders for the largest differences
        if (ladderAllocations.size() > ladders) {
          bricks -= ladderAllocations.poll();
        }
        // Return current position if out of bricks
        if (bricks < 0) {
          return i;
        }
      }
    }
    // Return last building if enough resources
    return heights.length - 1;
  }

  public static void main(String[] args) {
    Solution solution = new Solution();
    // Example 1
    System.out.println(
      solution.furthestBuilding(
        new int[] { 4, 12, 2, 7, 3, 18, 20, 3, 19 },
        10,
        2
      )
    );
    // Example 2
    System.out.println(
      solution.furthestBuilding(new int[] { 1, 5, 1, 2, 3, 4, 10000 }, 4, 1)
    );
    // Example 3
    System.out.println(
      solution.furthestBuilding(
        new int[] { 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20 },
        10,
        1
      )
    );
  }
}

Complexity Analysis

Time Complexity

  • Insertion into the Min-Heap: Each insertion operation into the min-heap takes time, where (m) is the number of elements in the heap.
  • Iterating through the buildings: The solution iterates through the buildings once, leading to operations where (n) is the number of buildings.
  • Heap operations: In the worst case, each building difference could be pushed into and popped from the heap once, leading to for heap operations since the heap size can grow up to (n - 1).

Overall, the time complexity of the solution is , where (n) is the number of buildings.

Space Complexity

  • Heap Storage: The min-heap can store up to differences in height between buildings, leading to a space complexity of .
  • Auxiliary Space: Constant space is used for variables, leading to .

Thus, the space complexity of the solution is , where (n) is the number of buildings.

🤖 Don't fully get this? Learn it with Claude

Stuck on Furthest Building You Can Reach? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Furthest Building You Can Reach** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Furthest Building You Can Reach** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Furthest Building You Can Reach**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Furthest Building You Can Reach**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes