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