问题描述
Please design a solution for the problem of Interval Partitioning, and analyze the complexity of your solution.
翻译
问题解释:可以理解为排课表问题
有n个会议/课 都有开始时间和结束时间,问最少需要几个教室才能进行完
思路
1.按照开始时间从早到晚开始排序
2.检查优先队列是否为空。(优先队列会按照结束时间进行从小到大排序)
如果优先队列为空。则将教室数++,同时将当前遍历的第i个任务 push_back到优先队列当中
如果优先队列不为空。检查优先队列对头的时间(最快结束时间的一个教室)是否结束时间早于第i个任务的开始时间。
如果早的话,pop队头,pushback(i),(相当于教室换主人)。
如果不早的话,新找个教室,res++,pushback(i),放入优先队列;
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
//以《最早开始时间划分》
/*
10
0 3
0 7
0 3
4 7
4 10
8 11
8 11
10 15
12 15
12 15
answer 3
*/
typedef struct lecture
{
int s, f;
};
bool cmp(lecture& a, lecture& b)
{
return a.s < b.s;
}
int solution(vector<lecture>& l)
{
sort(l.begin(), l.end(), cmp);//按开始时间排序
int res = 0;
priority_queue<int, vector<int>, greater<int>> pq;//优先队列,最早结束再最上面
for (int i = 0; i < l.size(); i++)
{
if (!pq.empty()&&l[i].s >=pq.top())//如果队列不空,如果开始时间大于优先队列顶部(最早结束的一个会议)
{
pq.pop();//将之前的记录删除,改为空教室
pq.push(l[i].f);//占用教室 ,并且设置结束时间
}
else
{
res++;
pq.push(l[i].f);//新教室
}
}
return res;
}
int main()
{
int n;
cout << "Please enter the number of lecture :" << endl;
cin >> n;
cout << "Please enter the starttime and finishtime of each lecture :" << endl;
vector<lecture>l(n);
for (int i = 0; i < n; i++)
{
cin >> l[i].s >> l[i].f;
}
int ans=solution(l);
cout << "The minimum number of classroom is :" << ans << endl;
return 0;
}
测试案例
10
0 3
0 7
0 3
4 7
4 10
8 11
8 11
10 15
12 15
12 15
运行结果
时间复杂度分析
排序算法 按使用归并排序计算,花费时间O(nlogn)
然后数组遍历从1-n 检查是否需要空教室 花费时间O(n)
总计时间复杂度O(nlogn)
速记
按照开始时间从早到晚开始排序
判断为空先push,pop之后要接push
开始时间和结束时间对比
优先队列greater