zoukankan      html  css  js  c++  java
  • [LeetCode] 1353. Maximum Number of Events That Can Be Attended

    Given an array of events where events[i] = [startDayi, endDayi]. Every event i starts at startDayi and ends at endDayi.

    You can attend an event i at any day d where startTimei <= d <= endTimei. Notice that you can only attend one event at any time d.

    Return the maximum number of events you can attend.

    Example 1:

    Input: events = [[1,2],[2,3],[3,4]]
    Output: 3
    Explanation: You can attend all the three events.
    One way to attend them all is as shown.
    Attend the first event on day 1.
    Attend the second event on day 2.
    Attend the third event on day 3.
    

    Example 2:

    Input: events= [[1,2],[2,3],[3,4],[1,2]]
    Output: 4
    

    Example 3:

    Input: events = [[1,4],[4,4],[2,2],[3,4],[1,1]]
    Output: 4
    

    Example 4:

    Input: events = [[1,100000]]
    Output: 1
    

    Example 5:

    Input: events = [[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]]
    Output: 7

    Constraints:

    • 1 <= events.length <= 105
    • events[i].length == 2
    • 1 <= startDayi <= endDayi <= 105

    最多可以参加的会议数目。给一个数组events,里面包含的是一些events的[startDay, endDay],表示每个event的开始日期和结束日期。你可以在[startDay, endDay]的任何一天去参加这个会议。请你返回你能参加的会议的最大数目。

    思路是贪心。这个题看着好像可以用扫描线的思路做,其实是没什么关系的,因为这道题不涉及区间左右边界的比较和尝试找overlap或者gap这一类的操作。正确的思路是你需要一个最小堆存储events的结束时间endDay。首先还是对input排序,这里我们是对events的startDay排序(注意跟最小堆存储内容的不同)。因为会议的结束日期最大可以到100000所以我们从1遍历到100000,意思是从第1天遍历到第100000天,然后去看每一天是否能参加event。

    在第d天的时候,

    • 如果此时最小堆不为空且堆顶元素(的结束时间)小于今天的天数d,则意味着我们无法去这个event了,直接从最小堆中弹出即可
    • 此时如果最小堆还有东西,剩下的东西都是一些event的结束时间endDay,且这些结束时间晚于今天的天数d,则弹出一个并且res++,意思是今天可以去其中的一个event
    • 如果有event的startDay是今天,则把他的endDay加入最小堆

    时间O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int maxEvents(int[][] events) {
     3         PriorityQueue<Integer> pq = new PriorityQueue<>();
     4         Arrays.sort(events, (a, b) -> a[0] - b[0]);
     5         int res = 0;
     6         int i = 0;
     7         int n = events.length;
     8         for (int d = 1; d <= 100000; d++) {
     9             // 会议结束时间已经早于今天的,就直接舍弃了,因为没法参加
    10             while (!pq.isEmpty() && pq.peek() < d) {
    11                 pq.poll();
    12             }
    13             // 会议开始时间是今天的,把他的结束时间放到pq中
    14             while (i < n && events[i][0] == d) {
    15                 pq.offer(events[i][1]);
    16                 i++;
    17             }
    18             // 目前pq中的元素都是在今天之前就开始的,并且结束时间 >= 今天
    19             if (!pq.isEmpty()) {
    20                 pq.poll();
    21                 res++;
    22             }
    23         }
    24         return res;
    25     }
    26 }

    LeetCode 题目总结

  • 相关阅读:
    python用于web题里写解密脚本
    改变checkbox和radio的默认样式
    div内元素垂直居中
    icheck.js插件
    glyphicons字形图标
    没有内容的span元素下掉问题
    临界区保护
    信号量的使用&生产者消费者问题
    空闲线程和钩子函数
    线程的时间片轮询调度
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13744163.html
Copyright © 2011-2022 走看看