Skip to content

Commit afe6de6

Browse files
committed
feat: add solutions to lc problem: No.1054
No.1054.Distant Barcodes
1 parent 2f8f67b commit afe6de6

File tree

8 files changed

+386
-39
lines changed

8 files changed

+386
-39
lines changed

solution/0700-0799/0767.Reorganize String/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@
5757

5858
时间复杂度 $O(n\log n)$,其中 $n$ 是字符串 `s` 的长度。
5959

60-
相似题目:[358. K 距离间隔重排字符串](/solution/0300-0399/0358.Rearrange%20String%20k%20Distance%20Apart/README.md)
60+
相似题目:
61+
62+
- [358. K 距离间隔重排字符串](/solution/0300-0399/0358.Rearrange%20String%20k%20Distance%20Apart/README.md)
63+
- [1054. 距离相等的条形码](/solution/1000-1099/1054.Distant%20Barcodes/README.md)
6164

6265
<!-- tabs:start -->
6366

solution/0800-0899/0854.K-Similar Strings/README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@
5555

5656
**方法二:A\* 算法(进阶)**
5757

58-
A\* 算法主要思想如下:
58+
A\* 搜索算法(A\* 读作 A-star),简称 A\* 算法,是一种在图形平面上,对于有多个节点的路径求出最低通过成本的算法。它属于图遍历和最佳优先搜索算法(英文:Best-first search),亦是 BFS 的改进。
59+
60+
A\* 算法主要步骤如下:
5961

6062
1. 将方法一中的 BFS 队列转换为优先队列(小根堆);
61-
1. 队列中的每个元素为 `(dist[state] + f(state), state)``dist[state]` 表示从起点到当前 state 的距离,`f(state)` 表示从当前 state 到终点的估计距离,这两个距离之和作为堆排序的依据;
62-
1. 当终点第一次出队时,说明找到了从起点到终点的最短路径,直接返回对应的 step;
63-
1. `f(state)` 是估价函数,并且估价函数要满足 `f(state) <= g(state)`,其中 `g(state)` 表示 state 到终点的真实距离;
64-
1. A\* 算法只能保证终点第一次出队时,即找到了一条从起点到终点的最小路径,不能保证其他点出队时也是从起点到当前点的最短路径。
63+
1. 队列中的每个元素为 `(dist[s] + f(s), s)``dist[s]` 表示从初始状态 $s_1$ 到当前状态 $s$ 的距离,`f(s)` 表示从当前状态 $s$ 到目标状态 $s_2$ 的估计距离,这两个距离之和作为堆排序的依据;
64+
1. 当终点第一次出队时,说明找到了从起点 $s_1$ 到终点 $s_2$ 的最短路径,直接返回对应的距离;
65+
1. `f(s)` 是估价函数,并且估价函数要满足 `f(s) <= g(s)`,其中 `g(s)` 表示 $s$ 到终点 $s_2$ 的真实距离;
66+
67+
需要注意的是,A\* 算法只能保证终点第一次出队时,即找到了一条从起点到终点的最小路径,不能保证其他点出队时也是从起点到当前点的最短路径。
6568

6669
复杂度分析:启发式搜索不讨论时空复杂度。
6770

solution/1000-1099/1054.Distant Barcodes/README.md

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,158 @@
3838

3939
<!-- 这里可写通用的实现逻辑 -->
4040

41+
**方法一:贪心 + 哈希表 + 优先队列(大根堆)**
42+
43+
先用哈希表 `cnt` 统计每种条形码的数量,然后将每种条形码及其数量存入优先队列(大根堆) 中,优先队列中的元素按照条形码数量从大到小排序。
44+
45+
重排条形码时,我们每次从堆顶弹出一个元素 `(v, k)`,将 `k` 添加到结果数组中,并将 `(v-1, k)` 放入队列 `q` 中。当队列长度大于 $1$ 时,弹出队首元素 `p`,若此时 `p.v` 大于 $0$,则将 `p` 放入堆中。循环,直至堆为空。
46+
47+
时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。其中 $n$ 为条形码数组的长度。
48+
49+
相似题目:[767. 重构字符串](/solution/0700-0799/0767.Reorganize%20String/README.md)
50+
4151
<!-- tabs:start -->
4252

4353
### **Python3**
4454

4555
<!-- 这里可写当前语言的特殊实现逻辑 -->
4656

4757
```python
48-
58+
class Solution:
59+
def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
60+
cnt = Counter(barcodes)
61+
h = [(-v, k) for k, v in cnt.items()]
62+
heapify(h)
63+
q = deque()
64+
ans = []
65+
while h:
66+
v, k = heappop(h)
67+
ans.append(k)
68+
q.append((v + 1, k))
69+
while len(q) > 1:
70+
p = q.popleft()
71+
if p[0]:
72+
heappush(h, p)
73+
return ans
4974
```
5075

5176
### **Java**
5277

5378
<!-- 这里可写当前语言的特殊实现逻辑 -->
5479

5580
```java
81+
class Solution {
82+
public int[] rearrangeBarcodes(int[] barcodes) {
83+
Map<Integer, Integer> cnt = new HashMap<>();
84+
for (int v : barcodes) {
85+
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
86+
}
87+
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[1] - a[1]);
88+
for (var e : cnt.entrySet()) {
89+
pq.offer(new int[] {e.getKey(), e.getValue()});
90+
}
91+
Deque<int[]> q = new ArrayDeque<>();
92+
int[] ans = new int[barcodes.length];
93+
int i = 0;
94+
while (!pq.isEmpty()) {
95+
var p = pq.poll();
96+
ans[i++] = p[0];
97+
p[1]--;
98+
q.offer(p);
99+
while (q.size() > 1) {
100+
p = q.pollFirst();
101+
if (p[1] > 0) {
102+
pq.offer(p);
103+
}
104+
}
105+
}
106+
return ans;
107+
}
108+
}
109+
```
110+
111+
### **C++**
112+
113+
```cpp
114+
using pii = pair<int, int>;
115+
116+
class Solution {
117+
public:
118+
vector<int> rearrangeBarcodes(vector<int>& barcodes) {
119+
unordered_map<int, int> cnt;
120+
for (auto& v : barcodes) {
121+
++cnt[v];
122+
}
123+
priority_queue<pii> pq;
124+
for (auto& [k, v] : cnt) {
125+
pq.push({v, k});
126+
}
127+
vector<int> ans;
128+
queue<pii> q;
129+
while (pq.size()) {
130+
auto p = pq.top();
131+
pq.pop();
132+
ans.push_back(p.second);
133+
p.first--;
134+
q.push(p);
135+
while (q.size() > 1) {
136+
p = q.front();
137+
q.pop();
138+
if (p.first) {
139+
pq.push(p);
140+
}
141+
}
142+
}
143+
return ans;
144+
}
145+
};
146+
```
56147
148+
### **Go**
149+
150+
```go
151+
func rearrangeBarcodes(barcodes []int) []int {
152+
cnt := map[int]int{}
153+
for _, v := range barcodes {
154+
cnt[v]++
155+
}
156+
pq := hp{}
157+
for k, v := range cnt {
158+
heap.Push(&pq, pair{v, k})
159+
}
160+
ans := []int{}
161+
q := []pair{}
162+
for len(pq) > 0 {
163+
p := heap.Pop(&pq).(pair)
164+
v, k := p.v, p.k
165+
ans = append(ans, k)
166+
q = append(q, pair{v - 1, k})
167+
for len(q) > 1 {
168+
p = q[0]
169+
q = q[1:]
170+
if p.v > 0 {
171+
heap.Push(&pq, p)
172+
}
173+
}
174+
}
175+
return ans
176+
}
177+
178+
type pair struct {
179+
v int
180+
k int
181+
}
182+
183+
type hp []pair
184+
185+
func (h hp) Len() int { return len(h) }
186+
func (h hp) Less(i, j int) bool {
187+
a, b := h[i], h[j]
188+
return a.v > b.v
189+
}
190+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
191+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(pair)) }
192+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
57193
```
58194

59195
### **...**

solution/1000-1099/1054.Distant Barcodes/README_EN.md

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,139 @@
3131
### **Python3**
3232

3333
```python
34-
34+
class Solution:
35+
def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
36+
cnt = Counter(barcodes)
37+
h = [(-v, k) for k, v in cnt.items()]
38+
heapify(h)
39+
q = deque()
40+
ans = []
41+
while h:
42+
v, k = heappop(h)
43+
ans.append(k)
44+
q.append((v + 1, k))
45+
while len(q) > 1:
46+
p = q.popleft()
47+
if p[0]:
48+
heappush(h, p)
49+
return ans
3550
```
3651

3752
### **Java**
3853

3954
```java
55+
class Solution {
56+
public int[] rearrangeBarcodes(int[] barcodes) {
57+
Map<Integer, Integer> cnt = new HashMap<>();
58+
for (int v : barcodes) {
59+
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
60+
}
61+
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[1] - a[1]);
62+
for (var e : cnt.entrySet()) {
63+
pq.offer(new int[] {e.getKey(), e.getValue()});
64+
}
65+
Deque<int[]> q = new ArrayDeque<>();
66+
int[] ans = new int[barcodes.length];
67+
int i = 0;
68+
while (!pq.isEmpty()) {
69+
var p = pq.poll();
70+
ans[i++] = p[0];
71+
p[1]--;
72+
q.offer(p);
73+
while (q.size() > 1) {
74+
p = q.pollFirst();
75+
if (p[1] > 0) {
76+
pq.offer(p);
77+
}
78+
}
79+
}
80+
return ans;
81+
}
82+
}
83+
```
84+
85+
### **C++**
86+
87+
```cpp
88+
using pii = pair<int, int>;
89+
90+
class Solution {
91+
public:
92+
vector<int> rearrangeBarcodes(vector<int>& barcodes) {
93+
unordered_map<int, int> cnt;
94+
for (auto& v : barcodes) {
95+
++cnt[v];
96+
}
97+
priority_queue<pii> pq;
98+
for (auto& [k, v] : cnt) {
99+
pq.push({v, k});
100+
}
101+
vector<int> ans;
102+
queue<pii> q;
103+
while (pq.size()) {
104+
auto p = pq.top();
105+
pq.pop();
106+
ans.push_back(p.second);
107+
p.first--;
108+
q.push(p);
109+
while (q.size() > 1) {
110+
p = q.front();
111+
q.pop();
112+
if (p.first) {
113+
pq.push(p);
114+
}
115+
}
116+
}
117+
return ans;
118+
}
119+
};
120+
```
40121
122+
### **Go**
123+
124+
```go
125+
func rearrangeBarcodes(barcodes []int) []int {
126+
cnt := map[int]int{}
127+
for _, v := range barcodes {
128+
cnt[v]++
129+
}
130+
pq := hp{}
131+
for k, v := range cnt {
132+
heap.Push(&pq, pair{v, k})
133+
}
134+
ans := []int{}
135+
q := []pair{}
136+
for len(pq) > 0 {
137+
p := heap.Pop(&pq).(pair)
138+
v, k := p.v, p.k
139+
ans = append(ans, k)
140+
q = append(q, pair{v - 1, k})
141+
for len(q) > 1 {
142+
p = q[0]
143+
q = q[1:]
144+
if p.v > 0 {
145+
heap.Push(&pq, p)
146+
}
147+
}
148+
}
149+
return ans
150+
}
151+
152+
type pair struct {
153+
v int
154+
k int
155+
}
156+
157+
type hp []pair
158+
159+
func (h hp) Len() int { return len(h) }
160+
func (h hp) Less(i, j int) bool {
161+
a, b := h[i], h[j]
162+
return a.v > b.v
163+
}
164+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
165+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(pair)) }
166+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
41167
```
42168

43169
### **...**
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using pii = pair<int, int>;
2+
3+
class Solution {
4+
public:
5+
vector<int> rearrangeBarcodes(vector<int>& barcodes) {
6+
unordered_map<int, int> cnt;
7+
for (auto& v : barcodes) {
8+
++cnt[v];
9+
}
10+
priority_queue<pii> pq;
11+
for (auto& [k, v] : cnt) {
12+
pq.push({v, k});
13+
}
14+
vector<int> ans;
15+
queue<pii> q;
16+
while (pq.size()) {
17+
auto p = pq.top();
18+
pq.pop();
19+
ans.push_back(p.second);
20+
p.first--;
21+
q.push(p);
22+
while (q.size() > 1) {
23+
p = q.front();
24+
q.pop();
25+
if (p.first) {
26+
pq.push(p);
27+
}
28+
}
29+
}
30+
return ans;
31+
}
32+
};

0 commit comments

Comments
 (0)