題目來源:力扣
題目描述:
在一個倉庫裏,有一排條形碼,其中第 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;
}
}