牛客网面试必刷TOP101-010贪心算法BM96 主持人调度(二)

描述

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

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

数据范围: 1≤n≤10^5 , −2^32≤starti​≤endi​≤2^31−1

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

示例1

输入:

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

返回值:

1

说明:

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

示例2

输入:

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

返回值:

2

说明:

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

备注:

 
   

1≤n≤10^5

starti​,endi​在int范围内

一、问题分析

首先读题,仔细看描述中的内容,发现需求是

1.有n个活动即将举办,每个活动都有开始时间与活动的结束时间,

2.第i个活动的开始时间是starti,第i个活动的结束时间是endi

3.举办某个活动就需要为该活动准备一个活动主持人。

4.一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动。

5.换句话说,一个主持人参与了第i个活动,那么该主持人在starti,endi这个时间段不能参与其他任何活动。

6.求为了成功举办这n个活动,最少需要多少名主持人。

7.数据范围:n大于等于1小于等于10的5次方

starti小于等于endi,且它们都大于等于-2的32次方小于等于2的31次方减1

8.复杂度要求:时间复杂度O(nlogn),空间复杂度O(n)

二、解题思路

1.首先按照开始时间排序

2.如果前一个活动的结束时间小于等于下一个活动的结束时间,那么同一名主持人就可以主持

3.如果下一个活动的开始时间在前一个活动结束时间之前,那么需要另外找一名主持人

4.但是如果再下一场活动的开始时间如果在前前一场活动结束之后,那么上一名主持人可以继续主持

5.为此我们需要记录主持人的结束时间,

6.或者使用贪心的方法,利用贪心思想,什么时候需要的主持人最少?肯定是所有的区间没有重叠

7.每个区间首和上一个的区间尾都没有相交的情况,我们就可以让同一位主持人不辞辛劳,一直主持了。

8.但是题目肯定不是这种理想的情况,那我们需要对交叉部分,判断需要增加多少位主持人。

9.具体做法:step1:利用辅助数组获取单独各个活动开始的时间和结束时间,然后分别开始时间和结束时间进行排序,方便后面判断是否相交。

step2:遍历n个活动,如果某个活动开始的时间大于之前活动结束的时候,当前主持人就够了,活动结束时间往后一个。

step3:若是出现之前活动结束时间晚于当前活动开始时间的,则需要增加主持人。

三、具体步骤

使用的语言是C

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 计算成功举办活动需要多少名主持人
 * @param n int整型 有n个活动
 * @param startEnd int整型二维数组 startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
 * @param startEndRowLen int startEnd数组行数
 * @param startEndColLen int* startEnd数组列数
 * @return int整型
 */

int compare(const void* a, const void* b) {
    int *A = (int*)a;
    int *B = (int*)b;
    return *A > *B;
}

int minmumNumberOfHost(int n, int** startEnd, int startEndRowLen, int* startEndColLen ) {
    // write code here
    int* start = (int*)malloc(sizeof(int) * n);
    int* end = (int*)malloc(sizeof(int) * n);
    for(int i = 0; i < n; i++) {
        start[i] = startEnd[i][0];
        end[i] = startEnd[i][1];
    }

    qsort(start, n, sizeof(int), compare);
    qsort(end, n, sizeof(int), compare);
    int i, j;
    for(i = 1, j = 0; i < n; i++) {
        // 如果某一场开始时间在某一场结束时间之后,那么不用安排额外的主持人,j表示不用多安排的主持人数。
        if(start[i] >= end[j]) {
            j++;
        }
    }
    return i - j;
}

你可能感兴趣的:(贪心算法,算法)