距离相等的条形码
难度:
标签:
题目描述
代码结果
运行时间: 66 ms, 内存: 17.5 MB
/*
* 思路:
* 1. 统计每个条形码的出现频率。
* 2. 将条形码按照出现频率从高到低排序。
* 3. 使用流来简化频率统计和排序。
*/
import java.util.*;
import java.util.stream.Collectors;
public class SolutionStream {
public int[] rearrangeBarcodes(int[] barcodes) {
Map<Integer, Long> countMap = Arrays.stream(barcodes)
.boxed()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
PriorityQueue<Map.Entry<Integer, Long>> maxHeap = new PriorityQueue<>((a, b) -> Long.compare(b.getValue(), a.getValue()));
maxHeap.addAll(countMap.entrySet());
int[] result = new int[barcodes.length];
int index = 0;
while (!maxHeap.isEmpty()) {
Map.Entry<Integer, Long> first = maxHeap.poll();
if (index > 0 && result[index - 1] == first.getKey()) {
Map.Entry<Integer, Long> second = maxHeap.poll();
result[index++] = second.getKey();
if (second.getValue() > 1) {
second.setValue(second.getValue() - 1);
maxHeap.add(second);
}
maxHeap.add(first);
} else {
result[index++] = first.getKey();
if (first.getValue() > 1) {
first.setValue(first.getValue() - 1);
maxHeap.add(first);
}
}
}
return result;
}
}
解释
方法:
这个题解使用了贪心算法和计数方法来重新排列条形码,以确保没有两个相邻的条形码是相同的。首先,使用Counter计算每个条形码出现的次数。然后,通过遍历这个计数字典,将条形码按照出现次数插入到结果列表中的适当位置。代码中使用了两个索引,odd_idx(奇数索引)和eve_idx(偶数索引),来分别填充奇数和偶数位置的条形码。如果某个条形码的计数小于等于n的一半,则优先填充到奇数位置;如果超过n的一半,则填充到偶数位置。这种策略保证了最终结果中任何相邻位置都不会有相同的条形码。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
题解中提到使用贪心算法和计数方法,能否详细解释为什么这种方法适用于此题目?
▷🦆
在处理计数超过n的一半的条形码时,为什么选择将它们填充到偶数位置?
▷🦆
如果条形码的总数n是奇数,填充到奇数索引的条形码数量是否会比偶数索引多一个?这会对最终的排列有什么影响?
▷🦆
代码中在填充条形码时,使用了两个while循环,第一个循环条件中包含`cnt <= half_n`,这是基于什么考虑?
▷