一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i 个活动,那么该主持人在 (starti,endi) 这个时间段不能参与其他任何活动。求为了成功举办这 n 个活动,最少需要多少名主持人。
数据范围:
复杂度要求:时间复杂度
,空间复杂度
2,[[1,2],[2,3]]
1
只需要一个主持人就能成功举办这两个活动
2,[[1,3],[2,4]]
2
需要两个主持人才能成功举办这两个活动
在int范围内
class Solution: def minmumNumberOfHost(self , n , startEnd ): starts=[] ends=[] for start,end in startEnd: starts.append(start); ends.append(end); starts.sort(); ends.sort() i,j,count,res=0,0,0,0 for time in starts: while(i<n and starts[i]<=time): i+=1 count+=1 while(j<n and ends[j]<=time): j+=1 count-=1 if res<count: res=count return res
class Solution: def minmumNumberOfHost(self , n , startEnd ): # 问题类比于 同一时间最多有多少个重叠区间 # 分别统计活动的开始时间和结束时间 start = [] end = [] for host in startEnd: start.append(host[0]) end.append(host[1]) start.sort() end.sort() # 统计同一时间的活动个数 count = 0 max_num = 0 # 活动索引号 i, j = 0, 0 while i < n and j < n: # 有新活动开始 if start[i] < end[j]: # 转到下个活动的开始时间作对比 i += 1 count += 1 # 记录过程中的最大个数 max_num = max(max_num, count) # 一个活动开始同时一个活动结束 elif start[i] == end[j]: i += 1 j += 1 # 一个活动结束 else: # 转到下个活动的结束时间作对比 j += 1 count -= 1 # 返回最大值(同一时间最多有多少个活动在举行) return max_num
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, new Comparator<int[]>(){
@Override
public int compare(int[] task1, int[] task2){
if(task1[0] != task2[0]){
return task1[0] < task2[0]? -1: 1;
}else{
return task1[1] < task2[1]? -1: 1;
}
}
});
PriorityQueue<Integer> pq = new PriorityQueue<>(); // 用于存储刚结束活动的end时间
pq.offer(startEnd[0][1]);
for(int i = 1; i < n; i++){
if(startEnd[i][0] >= pq.peek()){
// 有空闲不需要增加主持人,当前主持人可以紧接着干下一个活
pq.poll(); // 把上一个活出队,当前活会入队
}
pq.offer(startEnd[i][1]); // 如果跟上一个活时间重叠,就直接入队
}
return pq.size(); // 队列中积压的元素数量就是需要的主持人数
}
} from heapq import * class Solution: def minmumNumberOfHost(self , n: int, startEnd: List[List[int]]) -> int: # write code here pq = [] startEnd.sort() for i in range(len(startEnd)): if len(pq)>0 and pq[0]<=startEnd[i][0]: heappop(pq) heappush(pq,startEnd[i][1]) return len(pq)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 计算成功举办活动需要多少名主持人
* @param n int整型 有n个活动
* @param startEnd int整型vector<vector<>> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
* @return int整型
*/
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
// 时间复杂度O(NlogN),空间复杂度O(N)
const int N = startEnd.size();
int start[N], end[N];
for (int i = 0; i < N; ++i) {
start[i] = startEnd[i][0];
end[i] = startEnd[i][1];
}
sort(start, start + n);
sort(end, end + n);
int j = 0, res = 0;
for (int i = 0; i < N; ++i) {
if (start[i] >= end[j]) ++j;
else ++res;
}
return res;
}
}; class Solution: def minmumNumberOfHost(self , n: int, startEnd: List[List[int]]) -> int: ''' 思路: 解题思路 正在进行的活动数量只会在 各活动开始或结束时变化. 对正在进行的活动计数. ''' # 首先由开始时间排序. startEnd.sort(key=lambda x:x[0]) # 利用辅助数组,给每个活动的时间节点 标记start 或者 end. date = [] for i in range(n): date.append([startEnd[i][0], 'start']) date.append([startEnd[i][1], 'end']) # 再给date排序 date.sort(key=lambda x:x[0]) # 计数, 从左至右遍历时间轴,start标签则num++, end则num-- # res即当num最大时. res = 0; num = 0 for d in date: if d[1] == 'start': num += 1 elif d[1] == 'end': num -= 1 res = max(num, res) return res
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
// write code here
if (n == 1) return 1;
map<int, int> cnt; // 有序
for (auto& vec : startEnd) {
++cnt[vec[0]];
--cnt[vec[1]];
}
int ans = 0;
int curFreq = 0;
for (auto& [_, freq] : cnt) {
curFreq += freq;
ans = max(ans, curFreq);
}
return ans;
} 差分数组
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, ArrayList<ArrayList<Integer>> startEnd) {
// write code here
int[] startTime = new int[n];
int[] endTime = new int[n];
for (int i = 0; i < n; i++) {
startTime[i] = startEnd.get(i).get(0);
endTime[i] = startEnd.get(i).get(1);
}
Arrays.sort(startTime);
Arrays.sort(endTime);
int res = 0;
int i = 0, j = 0, count = 0;
while (i < n && j < n) {
if (startTime[i] < endTime[j]) {
count++;
i++;
} else if (startTime[i] > endTime[j]) {
count--;
j++;
} else {
// startTime[i] == endTime[j]
i++;
j++;
}
res = Math.max(res, count);
}
return res;
}
} class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算成功举办活动需要多少名主持人
* @param n int整型 有n个活动
* @param startEnd int整型vector<vector<>> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
* @return int整型
*/
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
// write code here
if(n==1) return 1;
if(n==0) return 0;
sort(startEnd.begin(),startEnd.end(), [](auto a, auto b){return (a[0]<b[0] || (a[0]==b[0] && a[1]<b[1]));});
vector<long long> hoster;
hoster.push_back(startEnd[0][1]);
for(int i=1;i<n;i++){
const int st=startEnd[i][0];
int pos=-1;
for(int j=0;j<hoster.size();j++){
if(st>=hoster[j]){
pos = pos <0 ? j :pos;
pos = hoster[j]<hoster[pos]?j:pos;
}
}
if(pos<0){
hoster.push_back(startEnd[i][1]);
}else{
hoster[pos]=startEnd[i][1];
}
}
return hoster.size();
}
}; class Solution: def minmumNumberOfHost(self , n: int, startEnd: List[List[int]]) -> int: # write code here sort_startend = sorted(startEnd, key = lambda x:x[0]) hosts =[] for it in sort_startend: if len(hosts)>0 and it[0] >= hosts[0]: heappop(hosts) heappush(hosts,it[1]) return len(hosts)
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算成功举办活动需要多少名主持人
* @param n int整型 有n个活动
* @param startEnd int整型ArrayList<ArrayList<>> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
* @return int整型
*/
public int minmumNumberOfHost (int n, int[][] startEnd) {
// write code here
//ArrayList<ArrayList<Integer>>
int[] start=new int[n];
int[] end=new int[n];
for(int i=0;i<=n-1;i++){
// start[i]=startEnd.get(i).get(0);
// end[i]=startEnd.get(i).get(1);
start[i]=startEnd[i][0];
end[i]=startEnd[i][1];
}
Arrays.sort(start);
Arrays.sort(end);
int host=1;
int j=0;
for(int i=1;i<=n-1;++i){
if(start[i]>=end[j]){
j++;
}else{
host++;
}
}
return host;
}
} # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # 计算成功举办活动需要多少名主持人 # @param n int整型 有n个活动 # @param startEnd int整型二维数组 startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间 # @return int整型 # class Solution: def minmumNumberOfHost(self , n: int, startEnd: List[List[int]]) -> int: # write code here ## 分离 开始时间和结束时间 start和end start = [i[0] for i in startEnd] end = [i[1] for i in startEnd] ## 排序 :如果有交叉,则就需要加一个主持人 start.sort() end.sort() ## 使用一个循环控制两个数组 num = 0 end_time = 0 for i in range(n): if start[i] >= end[end_time]: end_time += 1 ## 无交叉情况,后移end_time else: num += 1 ## 有交叉,主持人数量 + 1 return num
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 计算成功举办活动需要多少名主持人
* @param n int整型 有n个活动
* @param startEnd int整型vector<vector<>> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
* @return int整型
*/
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
// write code here
// 按开始时间从小到大排序开始时间相同,按结束时间从小到大排序。
sort(startEnd.begin(), startEnd.end(), [](auto& a, auto& b){
if (a[0] == b[0]) return a[1] < b[1];
return a[0] < b[0];
});
priority_queue<int, vector<int>, greater<int>> q;
int ans = 0;
for (int i = 0; i < n; ++i) {
//当前开始时间大等于先前最早结束活动时间,不用添加新的主持人
if (!q.empty() && startEnd[i][0] >= q.top()) {
q.pop();
}
// 否则添加新的主持人主持活动
else ++ans;
// 添加或更新一个新的结束时间
q.push(startEnd[i][1]);
}
return ans;
}
}; class Solution {
public:
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
if(startEnd.empty()) return 0;
sort(startEnd.begin(),startEnd.end(),[](vector<int>& a,vector<int>& b){
if(a[0]!=b[0])
return a[0] < b[0];//按照活动开始时间升序排序
else
return a[1] < b[1];//活动开始时间相等的,按照活动结束时间排序
});
//排序后,越靠前的活动都是尽早开始尽早结束
//用小顶堆存储活动的结束时间,每当有一个新的任务来时,如果这个任务的开始时间>=堆顶的最早结束时间,则主持人数目不变,反之主持人+1
priority_queue<int,vector<int>,greater<int> > min_q;
min_q.push(startEnd[0][1]);
for(int i=1;i<n;i++){
if(startEnd[i][0]>=min_q.top()) {// 有空闲不需要增加主持人,当前主持人可以紧接着干下一个活
min_q.pop();// 把上一个活出队,当前活会入队,即更新当前主持人赶下一个活的结束时间
}
min_q.push(startEnd[i][1]);// 如果跟上一个活时间重叠,就直接入队
}
return min_q.size();
}
}; 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) {
Arrays.sort(startEnd, (a, b) -> a[0] <= b[0] ? -1 : 1);
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
int ans = 0;
for (int[] interval : startEnd) {
while (!minHeap.isEmpty() && interval[0] >= minHeap.peek()) {
minHeap.poll();
}
minHeap.add(interval[1]);
ans = Math.max(ans, minHeap.size());
}
return ans;
}
} class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 计算成功举办活动需要多少名主持人
* @param n int整型 有n个活动
* @param startEnd int整型vector<vector<>> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
* @return int整型
*/
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
// write code here
map<int, int> mp;
for (const auto& item : startEnd) {
mp[item[0]]++;
mp[item[1]]--;
}
int cur = 0;
int ret = 0;
for (const auto& item : mp) {
cur += item.second;
if (cur > ret) ret = cur;
}
return ret;
}
};