[leetcode] The furthest building that can be reached (greedy)

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;
    }
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325663235&siteId=291194637