Skip to content

Commit 8b25c04

Browse files
committed
add: 1054.距离相等的条形码
1 parent c0bb406 commit 8b25c04

File tree

2 files changed

+270
-1
lines changed

2 files changed

+270
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,8 @@
250250
- [x] [【day-55】1046.最后一块石头的重量](./medium/heap/55.last-stone-weight.md)
251251
- [x] [【day-56】23.合并K个升序链表](./medium/heap/56.merge-k-sorted-lists.md)
252252
- [x] [【day-57】451.根据字符出现频率排序](./medium/heap/57.sort-characters-by-frequency.md)
253-
- [x] [【day-58】378. 有序矩阵中第K小的元素](./medium/heap/58.kth-smallest-element-in-a-sorted-matrix.md)
253+
- [x] [【day-58】378.有序矩阵中第K小的元素](./medium/heap/58.kth-smallest-element-in-a-sorted-matrix.md)
254+
- [x] [【day-59】1054.距离相等的条形码](./medium/heap/59.distant-barcodes.md)
254255

255256
## 专题篇
256257

medium/heap/59.distant-barcodes.md

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
# 1054. 距离相等的条形码
2+
3+
https://leetcode-cn.com/problems/distant-barcodes/
4+
5+
- [1054. 距离相等的条形码](#1054-距离相等的条形码)
6+
- [题目描述](#题目描述)
7+
- [方法1:直接排序](#方法1直接排序)
8+
- [思路](#思路)
9+
- [复杂度分析](#复杂度分析)
10+
- [代码](#代码)
11+
- [方法2:堆排序](#方法2堆排序)
12+
- [思路](#思路-1)
13+
- [复杂度分析](#复杂度分析-1)
14+
- [代码](#代码-1)
15+
- [方法3](#方法3)
16+
- [思路](#思路-2)
17+
- [复杂度分析](#复杂度分析-2)
18+
- [代码](#代码-2)
19+
20+
## 题目描述
21+
22+
```
23+
在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]。
24+
25+
请你重新排列这些条形码,使其中两个相邻的条形码 不能 相等。 你可以返回任何满足该要求的答案,此题保证存在答案。
26+
27+
 
28+
29+
示例 1:
30+
31+
输入:[1,1,1,2,2,2]
32+
输出:[2,1,2,1,2,1]
33+
示例 2:
34+
35+
输入:[1,1,1,1,2,2,3,3]
36+
输出:[1,3,1,3,2,1,2,1]
37+
 
38+
39+
提示:
40+
41+
1 <= barcodes.length <= 10000
42+
1 <= barcodes[i] <= 10000
43+
44+
来源:力扣(LeetCode)
45+
链接:https://leetcode-cn.com/problems/distant-barcodes
46+
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
47+
```
48+
49+
## 方法1:直接排序
50+
51+
### 思路
52+
53+
- 统计条形码的出现次数,按出现次数排序
54+
- 取出现次数最多的条形码,填充偶数位(0, 2, 4...)
55+
- 重复上一步骤直到偶数位填充完毕,然后开始填充奇数位(1, 3, 5...)
56+
57+
### 复杂度分析
58+
59+
- 时间复杂度:$O(NlogN)$,N 是 barcodes 的长度,统计条形码出现次数的时间是 $O(N)$,排序时间是 $O(klogk)$,k 是条形码总数,k 最坏情况下是 N。
60+
- 空间复杂度:$O(N)$,哈希表的空间,最坏的情况是每个条形码都不一样。
61+
62+
### 代码
63+
64+
JavaScript Code
65+
66+
```js
67+
/**
68+
* @param {number[]} barcodes
69+
* @return {number[]}
70+
*/
71+
var rearrangeBarcodes = function (barcodes) {
72+
const map = {};
73+
74+
for (let i = 0; i < barcodes.length; i++) {
75+
const barcode = barcodes[i];
76+
map[barcode] = (map[barcode] || 0) + 1;
77+
}
78+
79+
const list = Object.keys(map).map(b => [Number(b), map[b]]);
80+
list.sort((a, b) => a[1] - b[1])
81+
82+
const res = Array(barcodes.length);
83+
let i = 0;
84+
85+
while (list.length) {
86+
let [barcode, count] = list.pop();
87+
88+
while (count-- > 0) {
89+
if (i >= barcodes.length) i = 1;
90+
91+
res[i] = barcode;
92+
i += 2;
93+
}
94+
}
95+
return res;
96+
};
97+
```
98+
99+
## 方法2:堆排序
100+
101+
### 思路
102+
103+
- 统计条形码的出现次数,建堆
104+
- 从堆中取出现次数最多的条形码,填充偶数位(0, 2, 4...)
105+
- 重复上一步骤直到偶数位填充完毕,然后开始填充奇数位(1, 3, 5...)
106+
107+
### 复杂度分析
108+
109+
- 时间复杂度:$O(NlogN)$,N 是 barcodes 的长度,统计条形码出现次数的时间是 $O(N)$,每个条形码入堆出堆一次,时间是 $O(NlogN)$。
110+
- 空间复杂度:$O(N)$,哈希表的空间。
111+
112+
### 代码
113+
114+
JavaScript Code
115+
116+
```js
117+
/**
118+
* @param {number[]} barcodes
119+
* @return {number[]}
120+
*/
121+
var rearrangeBarcodes = function (barcodes) {
122+
const map = {};
123+
124+
for (let i = 0; i < barcodes.length; i++) {
125+
const barcode = barcodes[i];
126+
map[barcode] = (map[barcode] || 0) + 1;
127+
}
128+
129+
// 堆的数据结构 [barcode, count]
130+
const list = Object.keys(map).map(b => [Number(b), map[b]]);
131+
const heap = new MaxHeap(list, function comparator(inserted, compared) {
132+
return inserted[1] < compared[1];
133+
});
134+
135+
const res = Array(barcodes.length);
136+
let i = 0;
137+
138+
while (heap.size() > 0) {
139+
let [barcode, count] = heap.pop();
140+
141+
while (count-- > 0) {
142+
if (i >= barcodes.length) i = 1;
143+
144+
res[i] = barcode;
145+
i += 2;
146+
}
147+
}
148+
return res;
149+
};
150+
151+
// **************************************************
152+
153+
class Heap {
154+
constructor(list = [], comparator) {
155+
this.list = list;
156+
this.comparator = comparator;
157+
158+
this.init();
159+
}
160+
161+
init() {
162+
const size = this.size();
163+
for (let i = Math.floor(size / 2) - 1; i >= 0; i--) {
164+
this.heapify(this.list, size, i);
165+
}
166+
}
167+
168+
insert(n) {
169+
this.list.push(n);
170+
const size = this.size();
171+
for (let i = Math.floor(size / 2) - 1; i >= 0; i--) {
172+
this.heapify(this.list, size, i);
173+
}
174+
}
175+
176+
peek() {
177+
return this.list[0];
178+
}
179+
180+
pop() {
181+
const last = this.list.pop();
182+
if (this.size() === 0) return last;
183+
const returnItem = this.list[0];
184+
this.list[0] = last;
185+
this.heapify(this.list, this.size(), 0);
186+
return returnItem;
187+
}
188+
189+
size() {
190+
return this.list.length;
191+
}
192+
}
193+
194+
class MaxHeap extends Heap {
195+
constructor(list, comparator) {
196+
super(list, comparator);
197+
}
198+
199+
heapify(arr, size, i) {
200+
let largest = i;
201+
const left = Math.floor(i * 2 + 1);
202+
const right = Math.floor(i * 2 + 2);
203+
204+
if (left < size && this.comparator(arr[largest], arr[left]))
205+
largest = left;
206+
if (right < size && this.comparator(arr[largest], arr[right]))
207+
largest = right;
208+
209+
if (largest !== i) {
210+
[arr[largest], arr[i]] = [arr[i], arr[largest]];
211+
this.heapify(arr, size, largest);
212+
}
213+
}
214+
}
215+
```
216+
217+
## 方法3
218+
219+
### 思路
220+
221+
- 统计条形码的出现次数,建堆
222+
- 每次从堆中取两个出现次数最多的条形码,将它们加入排列结果中,然后数量分别减一后重新入堆
223+
- 直到堆中元素少于两个
224+
225+
### 复杂度分析
226+
227+
- 时间复杂度:$O(NlogN)$,N 是 barcodes 的长度,统计条形码出现次数的时间是 $O(N)$,每个条形码入堆出堆一次,时间是 $O(NlogN)$。
228+
- 空间复杂度:$O(N)$,哈希表的空间,最坏的情况是每个条形码都不一样。
229+
230+
### 代码
231+
232+
JavaScript Code
233+
234+
```js
235+
/**
236+
* @param {number[]} barcodes
237+
* @return {number[]}
238+
*/
239+
var rearrangeBarcodes = function (barcodes) {
240+
const map = {};
241+
242+
for (let i = 0; i < barcodes.length; i++) {
243+
const barcode = barcodes[i];
244+
map[barcode] = (map[barcode] || 0) + 1;
245+
}
246+
247+
// 堆的数据结构 [barcode, count]
248+
const list = Object.keys(map).map(b => [Number(b), map[b]]);
249+
const heap = new MaxHeap(list, function comparator(inserted, compared) {
250+
return inserted[1] < compared[1];
251+
});
252+
253+
const res = [];
254+
while (heap.size() > 1) {
255+
let [b1, cnt1] = heap.pop();
256+
let [b2, cnt2] = heap.pop();
257+
res.push(b1, b2)
258+
if (--cnt1 > 0) heap.insert([b1, cnt1])
259+
if (--cnt2 > 0) heap.insert([b2, cnt2])
260+
}
261+
if (heap.size()) {
262+
res.push(heap.pop()[0]);
263+
}
264+
return res
265+
};
266+
```
267+
268+
更多题解可以访问:[https://github.com/suukii/91-days-algorithm](https://github.com/suukii/91-days-algorithm)

0 commit comments

Comments
 (0)