【LeetCode 每日一题】1054. 距离相等的条形码

104 阅读1分钟

1054. 距离相等的条形码

难度:中等

时间:2023/05/29


在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]

请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。 你可以返回任何满足该要求的答案,此题保证存在答案。

示例 1:

输入:barcodes = [1,1,1,2,2,2]
输出:[2,1,2,1,2,1]

示例 2:

输入:barcodes = [1,1,1,1,2,2,3,3]
输出:[1,3,1,3,2,1,2,1]

提示:

  • 1 <= barcodes.length <= 10000
  • 1 <= barcodes[i] <= 10000

解题思路1:排序 + 分组

  • 使用哈希表或者桶计数统计barcodes中每个数出现的次数。
  • 按照出现次数从大到小排序(注意次数相同的情况下,相同的情况下,按照数字本身递增或者递减排序都可以)。
  • 遍历barcodes数组,将答案先填入ret数组的偶数位置。
  • 再遍历barcodes数组,再将答案填入ret数组的奇数位置。
  • Python
class Solution:
    def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
        cnt = Counter(barcodes)
        barcodes.sort(key=lambda x: (cnt[x], x), reverse=True)
        n = len(barcodes)
        ret = [0] * len(barcodes)
        ret[::2] = barcodes[: (n + 1) // 2]
        ret[1::2] = barcodes[(n + 1) // 2:]
        return ret
​
  • C++
class Solution {
public:
    vector<int> rearrangeBarcodes(vector<int>& barcodes) {
        auto mx = *max_element(barcodes.begin(), barcodes.end());
        vector<int> cnt(mx + 1);
        for (auto b : barcodes) {
            cnt[b] += 1;
        }
        sort(barcodes.begin(), barcodes.end(), [&](auto x, auto y){
            return cnt[x] > cnt[y] || (cnt[x] == cnt[y] && x > y);
        });
        auto n = barcodes.size();
        vector<int> ret(n);
        for (int k = 0, j = 0; k < 2; ++k) {
            for (int i = k; i < n; i += 2) {
                ret[i] = barcodes[j++];
            }
        }
        return ret;
    }
};

解题思路2:最大堆

  • 先记录每个数字出现的次数,再以 (次数,数字) 的形式存入大根堆中,每次弹出次数最大的元素,与结果数组的最后一个值做比较;

    • 如果相等继续弹出次数次大的元素加入结果,再将最大次数的数字加入结果
    • 如果不相等直接将次数最大的元素加入结果
  • 然后次数减一,判断剩余次数是否为 00, 为 00 则不再入堆,否则次数减一再次入堆。

class Solution {
public:
    vector<int> rearrangeBarcodes(vector<int>& barcodes) {
        unordered_map<int, int> rec;
        for (int i : barcodes) ++rec[i];
        priority_queue<pair<int, int>> pq;
        for (auto it : rec) pq.push({it.second, it.first});
        vector<int> ans;
        while (!pq.empty()) {
            auto [cnt, barcode] = pq.top(); pq.pop();
            ans.push_back(barcode);
            int cnt2, barcode2;
            if (!pq.empty()) {
                cnt2 = pq.top().first;
                barcode2 = pq.top().second;
                pq.pop();
                ans.push_back(barcode2);
                if (cnt2 > 1) pq.push({cnt2 - 1, barcode2});
            }
            if (cnt > 1) pq.push({cnt - 1, barcode});
        }
        return ans; 
    }
};