比赛的时候把 l 赋值为了0 结果挂了 估计数据有全是1的情况 然后mid = (0+1)/2 = 0了 然后除0 GG
必须要把 l 赋值为1 (这里题目没有出一个集合都分不了的情况) 我们可以判断一下如果全部加起来都小于k的话直接返回个空的vector 不然的话就让 l = 1
解释在代码里面
class Solution {
public:
/**
* 返回找到能够满足游戏胜利条件的子集,如果有多个子集满足条件,返回字典序最小的即可。
* @param n int整型 代表数字的数量
* @param k int整型 代表子集的大小
* @param s int整型vector 代表数字数组
* @return int整型vector
*/
int a[100010];
int l = 1,r = 1;
bool check(int x,int k){
int sum = 0; // 分成x个集合 每个集合的元素数量
for(int i = 1;i <= 100000;i++){
int t = a[i]/x;
if(t >= 1) // 如果t大于等于1 说明这个元素可以分成x个集合
sum += t;
}
return sum >= k; // 大于等于k说明 可以分成x个集合满足题意
}
vector<int> solve(int n, int k, vector<int>& s) {
// write code here
memset(a, 0, sizeof(a));
for(int i = 0;i < s.size();i++) a[s[i]]++;
for(int i = 1;i <= 100000;i++) r = max(r,a[i]);
int ans = 0;
while(l <= r){ // 二分出最多可以分出的集合数
int mid = (l+r)>>1;
if(check(mid,k)){
ans = mid;
l = mid+1;
}
else
r = mid-1;
}
vector<int> res;
if(ans == 0) return res;
for(int i = 1;i <= 100000;i++){
int t = a[i]/ans;
if(t >= 1){ // 这个元素可以分成ans个集合 加入到vector
for(int j = 0;j < t;j++){
res.push_back(i);
if(res.size() == k) // 够了的话直接return 保证数量为k且字典序最小
return res;
}
}
}
return res;
}
};
京公网安备 11010502036488号