具体思路:
差分,这道题还没发用传统区间排序做,可能会爆时间,并且区间重合度过高,判断起来十分费劲,目测要从左至右一直判断时间点;
具体代码:
1.差分:
class Solution {
public:
vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
vector<int>mins(n+2,0);
vector<int>ret;
for(auto& vec:bookings){
mins[vec[0]]+=vec[2];
mins[vec[1]+1]-=vec[2];
}
int cnt=0;
for(int i=1;i<=n;i++){
cnt+=mins[i];
ret.push_back(cnt);
}
return ret;
}
};
2.线段树:
using ll=long long;
struct node{
ll l,r,v,add;
node(int _l,int _r){
l=_l;
r=_r;
v=0;
add=0;
}
};
class Solution {
public:
vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
tree.resize(N*4);
build(1,1,n);
for(auto& book:bookings){
update(1, book[0], book[1], book[2]);
}
vector<int>ret;
for(int i=0;i<n;i++){
ret.push_back(query(1,i+1,i+1));
}
return ret;
}
void pushdown(int u){
//把父节点的区间变更值向下传递;
int add=tree[u]->add;
tree[u<<1]->v+=add;
tree[u<<1]->add+=add;
tree[u<<1|1]->v+=add;
tree[u<<1|1]->add+=add;
tree[u]->add=0;
}
void pushup(int u){
//向上传递;
tree[u]->v=tree[u<<1]->v+tree[u<<1|1]->v;
}
void update(int u,int l,int r,int v){
//该update函数为区间内的每一个元素都加上一个v;
//总体来说先先序向下,在后序向上;
if(l>tree[u]->r||r<tree[u]->l)
return;
if(l<=tree[u]->l&&tree[u]->r<=r){
//如果实际区间在目标区间之内;
tree[u]->v+=v;
tree[u]->add+=v;
}else{
//如果世纪区间并不完全在目标区间,即有交集,无交集;
pushdown(u);
int mid=tree[u]->l+(tree[u]->r-tree[u]->l)/2;
if(l<=mid)
update(u<<1, l, r, v);
if(r>mid)
update(u<<1|1,l,r,v);
pushup(u);
}
}
int query(int u,int l,int r){
if(l>tree[u]->r||r<tree[u]->l)
return 0;
if(l<=tree[u]->l&&tree[u]->r<=r){
return tree[u]->v;
}else{
pushdown(u);
int mid=tree[u]->l+(tree[u]->r-tree[u]->l)/2;
int ans=0;
if(l<=mid)
ans+=query(u<<1, l, r);
if(r>mid)
ans+=query(u<<1|1, l, r);
return ans;
}
}
void build(int u,int l,int r){
//构建线段树;
tree[u]=new node(l,r);
if(l!=r){
int mid=l+(r-l)/2;
build(u<<1, l, mid);
build(u<<1|1,mid+1,r);
}
}
private:
int N=20009;
vector<node*>tree;
};