⭐️前面的话⭐️
本篇文章介绍【距离相等的条形码】题解,题目标签【哈希表】, 【贪心】,【优先级队列】,展示语言c++/java。
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2023年5月14日🌴
✉️坚持和努力一定能换来诗与远方!
💭推荐书籍:📚《算法》,📚《算法导论》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
📌导航小助手📌
- ⭐️1054. 距离相等的条形码⭐️
- 🔐题目详情
- 💡解题思路
- 🔑源代码
- 🌱总结
⭐️1054. 距离相等的条形码⭐️
🔐题目详情
1054. 距离相等的条形码
在一个仓库里,有一排条形码,其中第 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: 利用哈希表计数,然后将哈希表转换为数组,按照频率从高到低进行排序,将元素按照隔空遍历的方式进行插入。
思路2:
第一步,使用哈希表计数。
第二步,将元素和数量绑定放入优先级队列当中。
第三步,每次取出出现次数最多的元素,和次多的元素插入到答案数组。
🔑源代码
思路1: 利用哈希表计数,然后将哈希表转换为数组,按照频率从高到低进行排序,将元素按照隔空遍历的方式进行插入。
代码:
c++
class Solution {
public:
static bool cmp(const pair<int, int>& e1, const pair<int, int>& e2)
{
if (e1.first != e2.first) return e1.first > e2.first;
else return e1.second < e2.second;
}
vector<int> rearrangeBarcodes(vector<int>& barcodes)
{
int size = barcodes.size();
//哈希表
unordered_map<int, int> cnt;
//统计每个数字出现的数量
for (int x : barcodes)
{
cnt[x]++;
}
//排序,模拟隔一个数插入一个数
vector<pair<int, int>> elems;
for (auto x : cnt)
{
elems.push_back({x.second, x.first});
}
//排序
sort(elems.begin(), elems.end(), cmp);
//模拟隔空插入
int index = 0;
vector<int> ans(size);
int ans_index = 0;
while (index < elems.size())
{
//优先插入元素个数最多的元素
if (elems[index].first > 0)
{
ans[ans_index] = elems[index].second;
elems[index].first--;
ans_index += 2;
if (ans_index >= size) ans_index = 1;
} else {
index++;
}
}
return ans;
}
};
java
class Solution {
public int[] rearrangeBarcodes(int[] barcodes) {
int size = barcodes.length;
//哈希表计数
Map<Integer, Integer> map = new HashMap<>();
for (int x : barcodes) {
map.put(x, map.getOrDefault(x, 0) + 1);
}
//转换为数组进行排序
List<int[]> list = new ArrayList<>();
for (Integer x : map.keySet()) {
list.add(new int[]{map.get(x), x});
}
//排序
Collections.sort(list, (a, b) -> {
if (b[0] != a[0]) return b[0] - a[0];
else return a[1] - b[1];
});
//模拟隔空插入
int index = 0;
int[] ans = new int[size];
int ansIndex = 0;
while (index < list.size()) {
if (list.get(index)[0] > 0) {
ans[ansIndex] = list.get(index)[1];
ansIndex += 2;
list.get(index)[0]--;
if (ansIndex >= size) ansIndex = 1;
} else index++;
}
return ans;
}
}
思路2:
第一步,使用哈希表计数。
第二步,将元素和数量绑定放入优先级队列当中。
第三步,每次取出出现次数最多的元素,和次多的元素插入到答案数组。
代码:
c++
class Solution {
public:
static bool cmp(const pair<int, int>& e1, const pair<int, int>& e2)
{
if (e1.first != e2.first) return e1.first > e2.first;
else return e1.second < e2.second;
}
vector<int> rearrangeBarcodes(vector<int>& barcodes)
{
int size = barcodes.size();
//哈希表计数
unordered_map<int, int> hash_map;
for (int x : barcodes) hash_map[x]++;
//加入优先级队列,大根堆
priority_queue<pair<int, int>> pq;
for (auto x: hash_map) pq.push({x.second, x.first});
//每次取出现频率最高的数插入
vector<int> ans;
while (pq.size() > 0)
{
pair<int, int> top1 = pq.top(); pq.pop();
if (pq.size() == 0)
{
ans.push_back(top1.second);
continue;
}
pair<int, int> top2 = pq.top(); pq.pop();
ans.push_back(top1.second);
ans.push_back(top2.second);
top1.first--; top2.first--;
if (top1.first > 0) pq.push(top1);
if (top2.first > 0) pq.push(top2);
}
return ans;
}
};
java
class Solution {
public int[] rearrangeBarcodes(int[] barcodes) {
//计数
HashMap<Integer, Integer> hash = new HashMap<>();
for (int x : barcodes) hash.put(x, hash.getOrDefault(x, 0) + 1);
//放入优先级队列,使用大根堆
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
if (a[0] != b[0]) return b[0] - a[0];
else return a[1] - b[1];
});
for (int x : hash.keySet()) {
pq.offer(new int[]{hash.get(x), x});
}
int[] ans = new int[barcodes.length];
int index = 0;
while (!pq.isEmpty()) {
int[] top1 = pq.poll();
if (pq.isEmpty()) {
ans[index++] = top1[1];
continue;
}
int[] top2 = pq.poll();
ans[index++] = top1[1];
ans[index++] = top2[1];
top1[0]--;
top2[0]--;
if (top1[0] > 0) pq.offer(top1);
if (top2[0] > 0) pq.offer(top2);
}
return ans;
}
}
🌱总结
贪心,哈希表计数,优先级队列。