LeetCode-1353.最多可以参加的会议数目 贪心+优先队列

这里是题目描述:LeetCode-1353.最多可以参加的会议数目

贪心+优先队列解法

我们使用贪心原则:在某一天有多个可以参加的会议时,我们选择结束时间最早的来参加

我们使用优先队列来存储当天可以参加的会议,优先级由会议结束时间来决定,保证可以在O(1)的时间开销内找到结束时间最早的会议并让它出队列,参加会议数+1;

那么,如何确定在某一天,哪些会议是可以参加的?我们事先对存储会议的数组以开始时间升序排列,在某一天时,就将所有以当天为开始时间的会议加入优先队,插入优先队列时间复杂度为O(logn);然后从队头清除结束时间早于当天但还没有被参加的会议;

至于优先队列如何来实现,我使用了java.util.PriorityQueue,大家也可以尝试自己用堆来实现优先队列

java题解代码:

class Solution {
    public int maxEvents(int[][] events) {
        if(events.length<=1)
        {
            return events.length;
        }
        Event[] eventArr=new Event[events.length];
        int eariest=events[0][0],latest=events[0][1];
        for(int i=0;i<events.length;i++)
        {
            eventArr[i]=new Event(events[i][0],events[i][1]);
            eariest=Math.min(eariest,events[i][0]);
            latest=Math.max(latest,events[i][1]);
        }
        Arrays.sort(eventArr,new EventComparator()); //以开始时间升序排序
        PriorityQueue<Event> canJoin=new PriorityQueue<>(); //存储可以参见的会议的优先队列,优先准则为会议结束时间,结束时间越早,优先级越高
        int numJoin=0; //可以参加的会议数
        int index=0;
        for(int day=eariest;day<=latest;day++)
        {
            for(;index<eventArr.length;index++) //将当天开始的会议加入优先队列
            {
                if(eventArr[index].start<=day)
                {
                    canJoin.offer(eventArr[index]);
                }
                else
                {
                    break;
                }
            }
            while(!canJoin.isEmpty()) //将在当天时已经结束的会议出队列
            {
                if(canJoin.peek().end<day)
                {
                    canJoin.remove();
                }
                else
                {
                    break;
                }
            }
            if(!canJoin.isEmpty()) //从优先队列队头选取最早结束的会议出队列,参加会议数+1
            {
                canJoin.remove();
                numJoin++;
            }
        }
        return numJoin;
    }
}
class Event implements java.lang.Comparable<Event> //定义会议类
{
    int start;
    int end;
    Event(int start,int end)
    {
        this.start=start;
        this.end=end;
    }
    @Override
    public int compareTo(Event e) //以结束时间作为比较标准
    {
        return this.end-e.end;
    }
}
class EventComparator implements java.util.Comparator<Event> //自定义的Event比较器
{
    @Override
    public int compare(Event e1,Event e2) //以开始时间作为比较标准
    {
        return e1.start-e2.start;
    }
}

时间复杂度:排序和向优先队列插入所有元素O(nlogn),所有元素优先队列出队O(n),因此O(nlogn)

空间复杂度:O(n)

你可能感兴趣的:(LeetCode-1353.最多可以参加的会议数目 贪心+优先队列)