In a warehouse, there is a row of barcodes, where the ith barcode is barcodes[i].
Rearrange the barcodes so that no two adjacent barcodes are equal. You may return any answer, and it is guaranteed an answer exists.
Examples:
Input: barcodes = {1, 1, 1, 2, 2, 2}
Output: {2, 1, 2, 1, 2, 1}
Explanation: In {2, 1, 2, 1, 2, 1}, no two adjacent barcodes are equal.Input: barcodes = {1, 1, 1, 1, 2, 2, 3, 3}
Output: {1, 3, 1, 3, 1, 2, 1, 2}
Explanation: In {1, 3, 1, 3, 1, 2, 1, 2}, no two adjacent barcodes are equal.
Approach: To solve the problem, follow the below idea:
The idea is to first use the map to get the frequency of characters. Then add them all into a heap , and if possible each iteration in while loop , pop out 2 elements from the heap. We have to pop out 2 elements because in case we just pop out one and put back in the heap, then there is a chance that the same element is still occurring the most number of times and hence it will become adjacent. so pop out 2 at a time to avoid this.
Step-by-step algorithm:
- Count the frequency of each barcode in the input vector using an unordered_map.
- Create a priority queue (max-heap) to store the barcodes sorted by their frequencies in descending order.
- Iterate through the priority queue, and for each barcode:
- Add the barcode to the rearranged vector, skipping every other position.
- Decrement the frequency of the barcode and add it back to the priority queue if its frequency is still greater than 0.
- If there's another barcode in the priority queue, add it to the next position in the rearranged vector.
- Return the rearranged vector.
Below is the implementation of the algorithm:
#include <bits/stdc++.h>
using namespace std;
vector<int> rearrangeBarcodes(vector<int>& barcodes)
{
// Create a hash map to store barcode frequencies.
unordered_map<int, int> map;
int n = barcodes.size();
for (int i = 0; i < n; i++) {
map[barcodes[i]]++;
}
// Create a priority queue to store barcode frequencies
// and corresponding values
priority_queue<pair<int, int> > heap;
for (auto it : map) {
heap.push({ it.second, it.first });
}
// Rearrange barcodes using the priority queue.
vector<int> result;
while (!heap.empty()) {
// Get the most frequent barcode and decrement its
// frequency.
pair<int, int> temp1 = heap.top();
heap.pop();
result.push_back(temp1.second);
temp1.first--; // Invert the negation for proper
// count
if (!heap.empty()) {
// Get the second most frequent barcode (if
// available) and decrement its frequency.
pair<int, int> temp2 = heap.top();
heap.pop();
result.push_back(temp2.second);
temp2.first--;
// Push back the second barcode only if it has
// remaining occurrences.
if (temp2.first > 0) {
heap.push(temp2);
}
}
// Push back the first barcode only if it has
// remaining occurrences.
if (temp1.first > 0) {
heap.push(temp1);
}
}
return result;
}
int main()
{
// Input: barcodes = [1, 1, 1, 2, 2, 2]
vector<int> barcodes = { 1, 1, 1, 2, 2, 2 };
vector<int> rearrangedBarcodes
= rearrangeBarcodes(barcodes);
cout << "Rearranged barcodes: ";
for (int barcode : rearrangedBarcodes) {
cout << barcode << " ";
}
cout << endl;
return 0;
}
Output
Rearranged barcodes: 2 1 2 1 2 1
Time complexity: O(n log m), where n is the size of the input vector and m is the number of unique barcodes.
Auxiliary space: O(m + n), where m is the number of unique barcodes and n is the size of the input vector.