1054. 距离相等的条形码
难度中等113
在一个仓库里,有一排条形码,其中第 i
个条形码为 barcodes[i]
。
请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。 你可以返回任何满足该要求的答案,此题保证存在答案。
示例 1:
输入:barcodes = [1,1,1,2,2,2]
输出:[2,1,2,1,2,1]
示例 2:
输入:barcodes = [1,1,1,1,2,2,3,3]
输出:[1,3,1,3,2,1,2,1]
提示:
1 <= barcodes.length <= 10000
1 <= barcodes[i] <= 10000
模拟
只要间隔着填入(索引超出则重置为1),并且先填入出现频率最大的数,就能得到结果。
先填入频率最大的数是为了防止其自身相遇。比如[1,2,2,3],[1,2,2,3,2]之类的。
class Solution:
def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
n = len(barcodes)
cnt = [0] * (10001)
for i in barcodes:
cnt[i] += 1
maxcnt, idx = 0, 0
# 找到最大频次
for i, v in enumerate(cnt):
if v > maxcnt:
maxcnt, idx = v, i
ans = [0] * n
# 将最大频次数放于偶数索引
j = 0
while cnt[idx]:
ans[j % n] = idx
j += 2
cnt[idx] -= 1
# 索引不重置,防止最大频次< n/2,>=n时重置为1,奇数索引开头
for i, v in enumerate(cnt):
if v == 0: continue
while cnt[i]:
if j >= n: j = 1
ans[j] = i
j += 2
cnt[i] -= 1
return ans
简洁写法:
https://leetcode.cn/problems/distant-barcodes/solution/tiao-xing-ma-zhong-xin-pai-lie-tan-xin-s-i92i/
class Solution:
def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
# 统计条形码频次
count = {}
for barcode in barcodes:
count[barcode] = count.get(barcode, 0) + 1
# 根据频次排序条形码
sorted_barcodes = sorted(count.items(), key=lambda x: x[1], reverse=True)
n = len(barcodes)
result = [0] * n
# 将条形码放置在偶数索引位置
idx = 0
for barcode, freq in sorted_barcodes:
for _ in range(freq):
result[idx] = barcode
idx += 2
if idx >= n:
idx = 1
return result
计数 + 优先队列
维护最大堆记录元素出现次数,主要是排序部分与上一个思路不同
class Solution:
def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
n = len(barcodes)
cnt = {}
for barcode in barcodes:
cnt[barcode] = cnt.get(barcode, 0) + 1
items = [(-val, key) for key, val in cnt.items()]
heapq.heapify(items)
cur = []
while items:
val, key = heapq.heappop(items)
cur += [key] * (-val)
j = 0
res = [0] * n
for i in range(0, n, 2):
res[i] = cur[j]
j += 1
for i in range(1, n, 2):
res[i] = cur[j]
j += 1
return res