You are given an array of integers, heights, representing the height of the building. There are also some bricks and ladders.
You start your journey from building 0 and move towards the buildings behind, possibly using bricks or ladders.
When moving from building i to building i+1 (subscripts start at 0):
If the height of the current building is greater than or equal to the height of the next building, you do not need a ladder or bricks
If the height of the current building is less than the height of the next building, you can use a ladder or (h[i+1] - h[i]) bricks
Returns the subscript of the furthest building you can reach if the given ladder and bricks are optimally used (subscripts start at 0).
Example 1:
Input: heights = [4,2,7,6,9,14,12], bricks = 5, ladders = 1
Output: 4
Explanation: Starting from building 0, you can complete the journey as follows:
- Reach building 1 without using bricks or ladders because 4 >= 2
- Use 5 bricks to reach building 2 . You have to use bricks or ladders because 2 < 7
- Reach building 3 without using bricks or ladders because 7 >= 6
- Use the only ladder to reach building 4. You have to use bricks or ladders because 6 < 9
cannot get past building 4 because there are no more bricks or ladders.
Example 2:
Input: heights = [4,12,2,7,3,18,20,3,19], bricks = 10, ladders = 2
Output: 7
Example 3:
Input: heights = [14,3,19,3], bricks = 17, ladders = 0
Output: 3
hint:
1 <= heights.length <= 10^5
1 <= heights[i] <= 10^6
0 <= bricks <= 10^9
0 <= ladders <= heights.length
Link: https://leetcode-cn.com/problems/furthest-building-you-can-reach
Thought analysis:
When going from low to high, there are two options: bricks and ladders.
Assuming that the current is i, diff = h[i+1]-h[i]. When diff > 0, you can choose to consume diff bricks and 1 ladder.
We can easily think that the most cost-effective use of ladders is to use them where the diff value is as large as possible. So it can be thought of:
Assuming that the number of ladders is k, and our current position is i, we need to find the diff with the largest k in [1,i]. This can be implemented with a small item heap. At each step, a small item heap with the top k is maintained, and the sum of the top k is recorded.
Go directly to the code.
//梯子无视diff,因此diff越大用梯子性价比越高
//最小堆记录[1,i]前k大,ptot记录前k大总和
//tot记录高度差总和
//取bricks >= tot-ptot的最右边界
#define ll long long
class Solution {
public:
int furthestBuilding(vector<int>& heights, int bricks, int ladders) {
ll tot = 0, ptot = 0;
int ans = 0;
int n = heights.size();
priority_queue<int,vector<int>,greater<int>> q;
for(int i = 1;i < n;i++)
{
int diff = heights[i]-heights[i-1];
if(diff > 0)
{
tot += diff;
if(q.size() < ladders) q.push(diff), ptot+=diff;
else
{
if(!q.empty() && diff > q.top())
{
ptot -= q.top();
q.pop();
q.push(diff);
ptot+=diff;
}
}
}
if(bricks >= tot-ptot) ans = i;
}
return ans;
}
};