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