2054. 两个最好的不重叠活动

364 阅读1分钟

这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

2054. 两个最好的不重叠活动

给你一个下标从 0 开始的二维整数数组 events ,其中 events[i] = [startTimei, endTimei, valuei] 。第 i 个活动开始于 startTimei ,结束于 endTimei ,如果你参加这个活动,那么你可以得到价值 valuei 。你 最多 可以参加 两个时间不重叠 活动,使得它们的价值之和 最大 。

请你返回价值之和的 最大值 。

注意,活动的开始时间和结束时间是 包括 在活动时间内的,也就是说,你不能参加两个活动且它们之一的开始时间等于另一个活动的结束时间。更具体的,如果你参加一个活动,且结束时间为 t ,那么下一个活动必须在 t + 1 或之后的时间开始。

 

示例 1:

图片.png

输入:events = [[1,3,2],[4,5,2],[2,4,3]] 输出:4 解释:选择绿色的活动 0 和 1 ,价值之和为 2 + 2 = 4 。

示例 2:

图片.png

输入:events = [[1,3,2],[4,5,2],[1,5,5]] 输出:5 解释:选择活动 2 ,价值和为 5 。

示例 3:

图片.png

输入:events = [[1,5,3],[1,5,1],[6,6,5]] 输出:8 解释:选择活动 0 和 2 ,价值之和为 3 + 5 = 8 。  

提示:

  • 2 <= events.length <= 10510^5
  • events[i].length == 3
  • 1 <= startTimei <= endTimei <= 10910^9
  • 1 <= valuei <= 10610^6

解题思路

1. 先将活动按起始时间从小到大进行排序

2. 维护一个最小堆,堆内元素代表活动的结束时间和对应价值

3. 遍历所有活动,如果堆内的活动结束时间小于当前活动的起始时间,又因为活动时间是从小到大进行排序的,所以当前堆内的活动是可以与后面任意活动一起参与的,因此我们可以维护maxVal记录下当前活动开始前,我们可以选择的最大价值

代码


class Solution {

public:

    int maxTwoEvents(vector<vector<int>>& events) {

        sort(events.begin(),events.end());

        int maxVal=0,res=0;

        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> priorityQueue;

        for (auto& event:events){

            while (priorityQueue.size()&&event[0]>priorityQueue.top().first)

            {

                maxVal=max(maxVal,priorityQueue.top().second);

                priorityQueue.pop();

            }

            res=max(res,maxVal+event[2]);

            if (event[2]>maxVal)

            priorityQueue.emplace(event[1],event[2]);

        }

        return res;

    }

};