1353. 最多可以参加的会议数目
力扣题目链接:
提示:https://leetcode.cn/problems/maximum-number-of-events-that-can-be-attended/
题目
首先得理解题目的意思:
- 一个二维数组中,在一维数组中存储着一个活动的开始时间和结束时间
- 一天只能参加一个活动
- 一个活动有持续的时间 (问题重点)
比如实例2 中:
第一天可以参加二维数组中 events[0] [] , [1, 2] 这个活动
第二天可以参加二维数组中 events[2] [] ,[1,2] 这个活动
第三天可以参加 [2, 3]
第四天可以参加 [3,4]
第一次尝试,使用贪心算法硬解:
思路:按照结束时间先后去参加,先结束的先参加。
- 先安装活动结束进行排序,如果活动结束时间相同,就按照活动开始时间排序
- 遍历二维数组,拿到每个一维数组(也就是活动的开始时间和活动的结束时间)
- 每次选取活动结束时间最早的,加入的set无序不重复的集合里。判断是否存在,存在则参加过,没存在则反之。
public int maxEvents(int[][] events) {
Arrays.sort(events, (o1, o2) -> o1[1] != o2[1] ? o1[1] - o2[1] : o1[0] - o2[0]);
Set<Integer> set = new HashSet<>();
for (int[] event : events) {
for (int i = event[0]; i <= event[1]; i++) {
if (!set.contains(i)) {
set.add(i);
break;
}
}
}
return set.size();
}
提交之后,显示超时
问题来源:
1.对于活动结束时间为 105次方来说,算法的时间复杂度过高了,执行时间过长
使用队列的形式+贪心算法的思想:
思路:见详细注释
package testProj;
import java.util.*;
/**
*
*/
public class test5 {
public static void main(String[] args) {
int[][] arr = {{1, 2}, {2, 3}, {3, 4}, {1, 2}};
System.out.println(maxEvents(arr));
}
public static int maxEvents(int[][] events) {
//先按照活动的开始时间排序
Arrays.sort(events, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
//创建一个队列 ,将活动结束时间加入到这个队列中。
// 每次去判断 当天 与 活动结束时间
PriorityQueue<Integer> queue = new PriorityQueue<>();
//curDay 当前天 index 活动1,2,3..., res输出 结果
int curDay = 0, index = 0, n = events.length, res = 0;
while (index < n || !queue.isEmpty()) {
if (queue.isEmpty()) {
//把活动的 结束时间加入到 queue中
queue.add(events[index][1]);
//重新更新curDay
curDay = events[index][0];
//方便遍历 下一个活动
index++;
}
//下一个活动的开始时间 小于 当前天数
while (index < n && events[index][0] <= curDay) {
queue.add(events[index][1]);
index++;
}
//选取结束时间最早的的会议,把当天分配给它 2>=1
if (queue.peek() >= curDay) {
res++;
curDay++;
}
queue.poll();
}
return res;
}
}