反悔贪心

摘要

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;
    }
};
posted @ 2026-07-21 15:53  庞加莱复现  阅读(2)  评论(0)    收藏  举报