leetcode:距離相等的條形碼

題目來源:力扣

題目描述:

在一個倉庫裏,有一排條形碼,其中第 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; 
        
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章