相同字母至少距离k

vector<int> rearrangeBarcodes(vector<int>& barcodes) {
    const int N = barcodes.size();
    unordered_map<int, int> cnt;
    for (int code : barcodes) {
        cnt[code]++;
    }

    auto cmp = [&cnt](int a, int b) { return cnt[a] < cnt[b]; };
    priority_queue<int, vector<int>, decltype(cmp)> pq(cmp);
    for (auto &e : cnt) pq.push(e.first);

    vector<int> ans;
    queue<int> freezed;
    while (!pq.empty()) {
        int code = pq.top(); pq.pop();
        ans.push_back(code);
        cnt[code]--;
        
        freezed.push(code);
        if (freezed.size() >= 2) { // 相同项至少距离2
            int released = freezed.front(); freezed.pop();
            if (cnt[released] > 0) pq.push(released);
        }
    }
    return ans;
}

Given a non-empty string **str **and an integer k, rearrange the string such that the same characters are at least distance **k **from each other.

All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string"".

Example 1:

str = "aabbcc", k = 3

Result: "abcabc"

The same letters are at least distance 3 from each other.

Example 2:

str = "aaabc", k = 3 

Answer: ""

It is not possible to rearrange the string.

Example 3:

str = "aaadbbcc", k = 2

Answer: "abacabcd"

Another possible answer is: "abcabcda"

The same letters are at least distance 2 from each other.
class Solution {
public:
    using Pair = pair<char, int>;
    string rearrangeString(string s, int k) {
        // 剩余最多的字母优先
        unordered_map<char, int> cnt;
        for (char c : s) cnt[c]++;
        auto cmp = [](const Pair &a, const Pair &b) {
            return a.second < b.second; // 最大堆
        };
        priority_queue<Pair, vector<Pair>, decltype(cmp)> pq(cmp);
        for (auto &e : cnt) pq.push(e);

        string ans;
        queue<Pair> freezed;
        while (!pq.empty()) {
            auto top = pq.top(); pq.pop();
            ans += top.first;
            top.second--;
            // 每个字母输出后都进freezed队列,包括{c,0}
            freezed.push(top);
            if (freezed.size() >= k) { // 队头解冻回堆
                auto released = freezed.front(); freezed.pop();
                if (released.second > 0) pq.push(released);
            }
        }
        return ans.size() == s.size() ? ans : "";
    }
};