You are given an integer array heights
representing the heights of buildings, some bricks
, and some ladders
.
You start your journey from building 0
and move to the next building by possibly using bricks or ladders.
While moving from building i
to building i+1
(0-indexed),
(h[i+1] - h[i])
bricks.Return the furthest building index (0-indexed) you can reach if you use the given ladders and bricks optimally.
Example 1:
heights = [4,2,7,6,9,14,12], bricks = 5, ladders = 1
Output: 4
Explanation: Starting at building 0, you can follow these steps:
It is impossible to go beyond building 4 because you do not have any more bricks or ladders.
Example 2:
heights = [4,12,2,7,3,18,20,3,19], bricks = 10, ladders = 2
Output: 7
Can you provide an efficient solution to determine the furthest reachable building index?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method to find the furthest reachable building involves exhaustively checking every possible path you can take. At each building, you consider whether you can reach the next one using your bricks or ladders, and explore all combinations of these choices.
Here's how the algorithm would work step-by-step:
def furthest_building_brute_force(heights, bricks, ladders):
max_reachable_building = 0
def explore_paths(current_building, remaining_bricks, remaining_ladders):
nonlocal max_reachable_building
max_reachable_building = max(max_reachable_building, current_building)
if current_building == len(heights) - 1:
return
height_difference = heights[current_building + 1] - heights[current_building]
if height_difference <= 0:
explore_paths(current_building + 1, remaining_bricks, remaining_ladders)
else:
# Try using bricks if possible
if remaining_bricks >= height_difference:
explore_paths(current_building + 1, remaining_bricks - height_difference, remaining_ladders)
# Try using ladders if possible
if remaining_ladders > 0:
explore_paths(current_building + 1, remaining_bricks, remaining_ladders - 1)
# Initiate recursive exploration
explore_paths(0, bricks, ladders)
return max_reachable_building
The key to solving this problem efficiently is to prioritize using the available bricks for the smallest height differences first and using ladders only for the larger differences. This ensures we maximize the distance we can travel. We can achieve this using a priority queue or a similar data structure that always gives us the smallest differences to cover.
Here's how the algorithm would work step-by-step:
import heapq
def furthestBuilding(heights, bricks, ladders):
height_differences = []
for i in range(len(heights) - 1):
difference = heights[i+1] - heights[i]
if difference > 0:
# Add the height difference assuming we use bricks
heapq.heappush(height_differences, difference)
bricks -= difference
# If we run out of bricks, use a ladder to replace the largest brick usage
if bricks < 0:
if ladders > 0 and height_differences:
# Use a ladder for the largest height difference
bricks += heapq.heappop(height_differences)
ladders -= 1
# If we still don't have enough resources, we can't proceed
else:
return i
return len(heights) - 1
Case | How to Handle |
---|---|
Empty heights array | Return 0 as we start at index 0; no movement is possible from an empty array. |
Heights array with only one building | Return 0, as we start at index 0 and no further movement is needed. |
Heights array where buildings are monotonically decreasing | Return heights.length -1 since no bricks or ladders are needed. |
Heights array where buildings are monotonically increasing and not enough bricks, but enough ladders | Return heights.length -1 since we can use a ladder for each increase. |
bricks and ladders are both zero, and heights are increasing | Return 0, as we can't move past the first building. |
Very large heights values leading to potential integer overflow when calculating differences | Use long data types to represent height differences to avoid potential overflow issues. |
Large heights array size (performance concerns) | Prioritize using a heap-based approach to efficiently track and use the smallest differences, ensuring O(n log k) time complexity where k is the number of ladders. |
Zero height difference between buildings | Continue traversal without using any bricks or ladders since no height difference exists. |