反悔贪心
摘要
1. 反悔贪心本质也是贪心,只是用堆存了反悔项。
2. 解题时要注意可反悔条件的书写不能遗漏
题目
可以到达的最远建筑(LeetCode 1642)
题目描述
给定建筑物高度数组 heights,以及砖块数 bricks 和梯子数 ladders。从第 0 栋楼出发向右移动: 下坡 / 平路无需消耗资源; 上坡可以用1 架梯子(可跨越任意高度),或消耗等于高度差的砖块。 求最远能到达的建筑物下标。
思路
反悔贪心
一般而言,反悔贪心复杂度为\(O(nlogn)\),而DP复杂度为\(O(nk)\)。反悔贪心相对于DP的优势在于反悔选择上——反贪用堆存储了所有可能的反悔方式,最优反悔选项直接从堆顶取出,但DP不具有此优势。
注意:反贪中的"反悔项"也要"可贪",才能使用反贪算法。正因如此,我们常用堆存储反悔项。
解题过程
见代码。在具体解题时,需要着重考虑可反悔条件。
需着重注意下述代码中可反悔条件的书写
复杂度
时间复杂度: \(O(nlogn)\)
空间复杂度: \(O(n)\)
Code
class Solution {
public:
int furthestBuilding(vector<int>& heights, int bricks, int ladders) {
priority_queue<int> q;
int n = heights.size()-1;
for(int i=1;i<=n;i++){
if (heights[i-1]>=heights[i])
continue;
int diff = heights[i]-heights[i-1];
if(bricks<diff && ladders && !q.empty() && q.top()>diff){
int t = q.top();
bricks+=t; q.pop(); ladders--;
}
if(bricks>=diff){
bricks-=diff;
q.push(diff);
}
else if(ladders) ladders--;
else return i-1;
}
return n;
}
};


浙公网安备 33010602011771号