2910. 合法分组的最少组数
思路:贪心+哈希表。细节看注释
class Solution {
public:
bool check(int u,vector<int> v,int &mn){
int ans=0;
bool flag=1;
for(int i=0;i<v.size();i++){
if(v[i]/u<v[i]%u){如果v[i]%u大于v[i]/u,也就是说会出现小于u的数
flag=0;
break;
}else{
//先尽量把u+1的盒子装好,剩下的v[i]%(u+1),就可以通过再加一盒组合成u*x+(u+1)*y==v[i]
ans+=v[i]/(u+1);
if(v[i]%(u+1)) ans++;
}
}
if(flag){
if(mn>ans) mn=ans;
else flag=0;
}
return flag;
}
int minGroupsForValidAssignment(vector<int>& balls) {
//先统计出现的编号所对应的次数
unordered_map<int ,int> mp;
for(int i=0;i<balls.size();i++){
mp[balls[i]]++;
}
vector<int> v;//v表示所有编号的次数
int k=100000;//k表示的是最小的盒子容量
for(auto t:mp){
v.push_back(t.second);
k=min(k,t.second);//找到最小的出现次数,因为我们是只允许出现k,k+1容量的盒子。
}
int mn=balls.size();//
//从最小的出现次数开始往后递减
for(;k>0;k--){
if(check(k,v,mn)) break;
}
return mn;
}
};