BM96 主持人调度(二)

1.题目描述

有 n 个活动即将举办,每个活动都有开始时间与活动的结束时间,第 i 个活动的开始时间是 starti ,第 i 个活动的结束时间是 endi ,举办某个活动就需要为该活动准备一个活动主持人。

一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i 个活动,那么该主持人在 (starti,endi) 这个时间段不能参与其他任何活动。求为了成功举办这 n 个活动,最少需要多少名主持人。

数据范围: 1≤n≤1051≤n≤105 , −232≤starti≤endi≤231−1−232≤starti​≤endi​≤231−1

复杂度要求:时间复杂度 O(nlog⁡n)O(nlogn) ,空间复杂度 O(n)O(n)

示例1

输入:

2,[[1,2],[2,3]]

返回值:

1

说明:

只需要一个主持人就能成功举办这两个活动      

示例2

输入:

2,[[1,3],[2,4]]

返回值:

2

说明:

需要两个主持人才能成功举办这两个活动      

备注:

1≤n≤1051≤n≤105

starti,endistarti​,endi​在int范围内

2.解题思路

使用一个优先级队列(小根堆)存储每一个活动的结束时间,如果当前遍历到的活动的开始时间>=堆顶元素的结束时间,就说明这两个活动可以共同使用一个主持人,需要将堆顶元素出队,然后再把当前活动的结束时间入队,只有两个活动有时间上的冲突(交集)时,才需要新增一个主持人,最终队列中的元素个数就是n个活动所需的最少的主持人数量。

注:

1.我们需要按照活动的开始时间递增排序,当两个活动具有相同的开始时间时,再按照它们的结束时间升序排列;这样能保证我们每一次判断都是局部最优,使用了贪心的思路。

2.在自定义排序规则时,重写Comparator接口中的compare方法时,因为开始时间和结束时间是一个2^32量级的数,不能使用 return t1[0] == t2[0] ? t1[1] - t2[1] : t1[0] - t2[1],可能会发生整数范围的溢出,所以需要调用Integer的compare方法进行两个数的对比

3.代码实现

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算成功举办活动需要多少名主持人
     * @param n int整型 有n个活动
     * @param startEnd int整型二维数组 startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
     * @return int整型
     */
    public int minmumNumberOfHost (int n, int[][] startEnd) {
        // write code here
        Arrays.sort(startEnd, (t1, t2) -> {
            if (t1[0] == t2[0]) {
                return Integer.compare(t1[1], t2[1]);
            } else {
                return Integer.compare(t1[0], t2[0]);
            }
        });
        //定义一个优先级队列,用于存储每一个活动的结束时间
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        pq.offer(startEnd[0][1]);
        for (int i = 1; i < n; i++) {
            if (!pq.isEmpty() && startEnd[i][0] >= pq.peek()) {
                pq.poll();
            }
            pq.offer(startEnd[i][1]);
        }
        return pq.size();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值