题目来源:力扣
题目描述:
在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]。
请你重新排列这些条形码,使其中两个相邻的条形码 不能 相等。 你可以返回任何满足该要求的答案,此题保证存在答案。
============================================================
示例 1:
输入:[1,1,1,2,2,2]
输出:[2,1,2,1,2,1]
示例 2:
输入:[1,1,1,1,2,2,3,3]
输出:[1,3,1,3,2,1,2,1]
=========================================================
审题:
对于该题,我一开始使用尝试使用回溯法,首先使用键值对数据结构统计每一数值出现的次数,然后在回溯的每一步,当前可选的子集为与上一值不相同,且值不为0的键.该算法理论上可行,但我们知道,回溯法的时间复杂度是非常高的,因此不出所料,在数据集较大时,提示该方法超出时间限制,后面会给出其具体代码,供大家参考.
后面,看了其他人写的题解.该思路的核心是,要构建符合题目要求的条形码,我们每次应当选择出现次数最多的两个不同值.由于该题目保证给定的条形码一定存在答案,即相邻数值不相同,因此使用该方法可以构建得到符合要求的结果.我们使用最大优先队列保存数值.
java算法
回溯算法
class Solution {
//使用回溯法构建
boolean find = false;
private void construct(Map<Integer, Integer> map, int[]barcodes, int i){
if(find)
return;
if(i == barcodes.length){
find = true;
return;
}
for(int key: map.keySet()){
if(map.get(key) > 0 && !find){
if(i == 0 || barcodes[i-1] != key){
barcodes[i] = key;
map.put(key, map.get(key)-1);
construct(map, barcodes, i+1);
map.put(key, map.get(key) + 1);
}
}
}
}
public int[] rearrangeBarcodes(int[] barcodes) {
Map<Integer, Integer> map = new HashMap<>();
for(int i: barcodes){
map.put(i,
map.getOrDefault(i, 0)+1);
}
int[] rearrange = new int[barcodes.length];
construct(map, rearrange, 0);
return rearrange;
}
}
基于最大优先队列
import java.util.AbstractMap.SimpleEntry;
class Solution {
//由于java的优先队列默认为最小优先队列,因此我们需要自定义比较器
class EntryCompare implements Comparator<Map.Entry<Integer, Integer>>{
public int compare(Map.Entry<Integer, Integer> a, Map.Entry<Integer, Integer> b){
return Integer.compare(b.getValue(), a.getValue());
}
}
public int[] rearrangeBarcodes(int[] barcodes) {
HashMap<Integer, Integer> map = new HashMap<>();
for(int val : barcodes)
map.put(val, map.getOrDefault(val,0)+1);
PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>(10, new EntryCompare());
for (Map.Entry<Integer, Integer> entry: map.entrySet())
pq.offer(entry);
int[] rearrange = new int[barcodes.length];
int i = 0;
if(map.size() == 1)
rearrange[i++] = pq.poll().getKey();
while(i < barcodes.length){
Map.Entry<Integer, Integer> m1 = pq.poll();
Map.Entry<Integer, Integer> m2 = pq.poll();
rearrange[i++] = m1.getKey();
if(i < barcodes.length)
rearrange[i++] = m2.getKey();
pq.offer(new SimpleEntry<Integer, Integer>(m1.getKey(), m1.getValue()-1));
pq.offer(new SimpleEntry<Integer, Integer>(m2.getKey(), m2.getValue()-1));
}
return rearrange;
}
}