6170. 会议室 III(关于自定义sort的惨案)
思路就很简单。
第一种方法就是直接按照题意模拟可以过。
class Solution {
public:
struct node{
long long x;
int id;
bool operator<(const node&a)const{
return x==a.x?id>a.id:x>a.x;
}
};
int mostBooked(int n, vector<vector<int>>& a) {
int m =a.size();
sort(a.begin(),a.end());
// priority_queue<node>q;
vector<int>ans(n);
vector<long long>b(n);
for(int i=0;i<m;i++){
int l =a[i][0],r=a[i][1];
int ok = 0;
int mn = 0;
for(int j=0;j<n;j++){
if(b[j]<=l){
ans[j]++;
b[j] = r;
ok = 1;break;
}
if(b[j]<b[mn]) mn = j;
}
if(!ok){
ans[mn]++;
b[mn]+=r-l;
}
}
int res=0;
for(int i=0;i<n;i++)
if(ans[i]>ans[res]){
res=i;
}
return res;
}
};
第二种方法:优先队列维护每个会议室的结束时间和id。
如果当前结束时间<区间l 那么修改结束时间为l。
因为可能存在多个满足条件的,需要取最小的id。
class Solution {
public:
struct node{
long long x;
int id;
bool operator<(const node&a)const{
return x==a.x?id>a.id:x>a.x;
}
};
int mostBooked(int n, vector<vector<int>>& a) {
int m =a.size();
sort(a.begin(),a.end(),[&](auto &u,auto &v){
return u[0]<v[0];
});
priority_queue<node>q;
vector<int>ans(n);
for(int i=0;i<n;i++) q.push({0,i});
//int now = 0;
int idx = 0;
while(!q.empty() && idx<m){
auto u =q.top();q.pop();
long long x=u.x;
int id=u.id;
int l = a[idx][0],r=a[idx][1];
if(x<l){
//printf("(%d,%d,%d)\n",id,x,r);
//ans[id]++;
q.push({l,id});
}
else {
//printf("-(%d,%d,%d)\n",id,x,x+r-l);
idx++;
ans[id]++;
q.push({x+r-l,id});
}
}
int res=0;
for(int i=0;i<n;i++)
if(ans[i]>ans[res]){
res=i;
}
return res;
}
};
第三种方法,使用mutliset维护。
class Solution {
public:
struct node{
long long x;
int id;
bool operator<(const node&a)const{
return x==a.x?id>a.id:x>a.x;
}
};
int mostBooked(int n, vector<vector<int>>& a) {
int m =a.size();
sort(a.begin(),a.end(),[&](auto &u,auto &v){
return u[0]<v[0];
});
// priority_queue<node>q;
vector<int>ans(n);
multiset<pair<long long,int> >v;
for(int i=0;i<n;i++){
v.insert({0,i});
}
for(int i=0;i<m;i++){
int l =a[i][0],r=a[i][1];
auto it = v.upper_bound({l,n});
if(it==v.begin()){
long long x = it->first,id=it->second;
v.erase(it);
v.insert({x+r-l,id});
// printf("id=%d\n",id);
ans[id]++;
continue;
}
--it;
int mn = n;
auto tmp =v.begin();
while(it!=v.begin()){
if(mn>it->second){
mn = it->second;
tmp = it;
}
--it;
}
if(mn>it->second){
mn = it->second;
tmp = it;
}
ans[mn]++;
v.erase(tmp);
v.insert({r,mn});
}
// puts("");
int res=0;
for(int i=0;i<n;i++)
if(ans[i]>ans[res]){
res=i;
}
return res;
}
};
重要!!!
在重载排序函数的时候,一定要传引用,不要传值。
此题如果传值,相当于每次比较都需要复制一次vector,开销非常大,在leetcode的评测环境下会直接导致。
sort(a.begin(),a.end(),[&](auto &u,auto &v){//正确写法
return u[0]<v[0];
});
sort(a.begin(),a.end(),[&](auto u,auto v){//错误写法
return u[0]<v[0];
});