比赛的时候把 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; } };