一、题目
给你一个数组 events,其中 events[i] = [startDayi, endDayi] ,表示会议 i 开始于 startDayi ,结束于 endDayi 。
你可以在满足 startDayi <= d <= endDayi 中的任意一天 d 参加会议 i 。注意,一天只能参加一个会议。
请你返回你可以参加的 最大 会议数目。
链接:https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended
二、思路
区间调度问题变种,贪心算法:选择最早结束的会议。注意:不同的是几天的会议只需要参加一天就算参加了。
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class ConferenceOne {
public int maxEvents(int[][] events) {
int n = events.length;
// 按照开始时间升序排列,这样,对于相同开始时间的会议,可以一起处理
Arrays.sort(events, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
// 小顶堆:用于高效的维护最小的 endDay
PriorityQueue<Integer> queue = new PriorityQueue<>();
int result = 0;
int currentDay = 1;
int i = 0;
while (i < n || !queue.isEmpty()) {
// 将所有开始时间等于 currentDay 的会议的结束时间放到小顶堆
while (i < n && events[i][0] == currentDay) {
queue.offer(events[i][1]);
i++;
}
// 将已经结束的会议弹出堆中,即堆顶的结束时间小于 currentDay 的
while (!queue.isEmpty() && queue.peek() < currentDay) {
queue.poll();
}
// 选择结束时间最小的会议参加
if (!queue.isEmpty()) {
// 参加的会议,就从队列出队
queue.poll();
result++;
}
//遍历下一天
currentDay++;
}
return result;
}
}