题目:3479. 水果成篮 III
思路:线段树,时间复杂度0(nlogn)。
此题的进阶版:(LeetCode 每日一题) 3477. 水果成篮 II (暴力)
线段树来维护区间闲置水果篮的最大容量。
C++版本:
class Solution {
public:
vector<int> tre;
// 维护两个子区间闲置水果篮的最大容量
void push_up(int u){
tre[u]=max(tre[u<<1],tre[u<<1|1]);
}
// 构建线段树
void build(int u,int l,int r, vector<int>& baskets){
if(l==r){
tre[u]=baskets[l];
return ;
}
int mid=(l+r)/2;
build(u<<1,l,mid,baskets);
build(u<<1|1,mid+1,r,baskets);
push_up(u);
}
// 查询区间内是否有闲置水果篮可装下x大小的水果
bool query(int u,int l,int r,int x){
if(tre[u]<x) return false;
if(l==r){
//可以的话,就置为-1,表示被使用
tre[u]=-1;
return true;
}
int mid=(l+r)/2;
bool flag=query(u<<1,l,mid,x);
if(flag){
push_up(u);
return true;
}
flag = query(u<<1|1,mid+1,r,x);
if(flag){
push_up(u);
}
return flag;
}
int numOfUnplacedFruits(vector<int>& fruits, vector<int>& baskets) {
int n=fruits.size();
tre.resize(n<<2);
// 构建线段树
build(1,0,n-1,baskets);
int ans=0;
// 遍历所有水果
for(auto x:fruits){
// 查询是否可填入
if(query(1,0,n-1,x)==true){
ans++;
}
}
return n-ans;
}
};