Skyscraper Furthest Distance
## description
## Skyscraper Furthest Distance
A player needs to traverse between skyscrapers, carrying springs and sandbags. The heights of these buildings vary.
If the next building's rooftop is lower than or equal to the current one, the player can move freely.
If the next rooftop is higher, the player must either:
- –Use sandbags (each sandbag increases the player's height by 1; if the sum of the current height and sandbags equals the next rooftop's height, the player can move forward).
- –Use springs to jump directly to the next rooftop, regardless of height difference.
The goal is to determine the index of how far the player can travel.
Example 1:
1Input: heights = [2, 3, 5, 1, 7], springs = 1, sandbags = 2
2Output: 3
3Explanation: Use 1 sandbag to move from 2 -> 3, use 1 spring to move from 3 -> 5, 5 -> 1 is a free move. Cannot move further, therefore, index 3.Example 2:
1Input: heights = [4, 2, 2, 6, 3, 7], springs = 1, sandbags = 4
2Output: 5
3Explanation: 4 -> 2 free, 2 -> 2 free, 2 -> 6 use 4 sandbags, 6 -> 3 free, 3 -> 7, need 4 sandbags, use spring. Can also use spring at 2 -> 6 instead, same resultExample 3:
1Input: heights = [1, 5, 2, 3, 10], springs = 1, sandbags = 3
2Output: 3
3Explanation: 1 -> 5 must use spring, 5 -> 2 free, 2 -> 3 use 1 sandbag, 3 -> 10 need 7 sandbags or 1 spring, don't have either, return 3## notes
### Intuition
Springs are most valuable for the largest height differences. Use sandbags first, and when you run out, retroactively convert the largest sandbag usage to a spring.
### Implementation
Use a max heap to track height differences. For each upward jump, subtract from sandbags and add the difference to the heap. If sandbags go negative and no springs remain, return the current index. Otherwise, use a spring by popping the largest jump from the heap and adding those sandbags back. Continue until the end.
### Edge-cases
Python's heapq is a min heap—negate values to simulate max heap behavior. Remember to negate again when popping.
- –Time: O(n log n) — heap operations for each building
- –Space: O(n) — heap stores jump sizes
### Complexity
## solution
1from typing import List
2import heapq
3
4class Solution:
5 def furthestDistance(self, heights: List[int], springs: int, sandbags: int) -> int:
6 # Optimal (min heap, O(n log n) time, O(n) space)
7 max_heap = []
8 # O(n)
9 for i in range(len(heights) - 1):
10 diff = heights[i + 1] - heights[i]
11 if diff <= 0:
12 continue
13
14 sandbags -= diff
15 # O(log n)
16 heapq.heappush(max_heap, -diff)
17
18 if sandbags < 0:
19 if springs == 0:
20 return i
21 springs -= 1
22 # O(log n)
23 sandbags += -heapq.heappop(max_heap)
24 return len(heights) - 1
25
26if __name__ == "__main__":
27 # Include one-off tests here or debugging logic that can be run by running this file
28 # e.g. print(solution.two_sum([1, 2, 3, 4], 3))
29 solution = Solution()
30