Skip to content

Commit 70f47a9

Browse files
committed
feat: add solutions to lc problem: No.1670
No.1670.Design Front Middle Back Queue
1 parent d58502c commit 70f47a9

File tree

6 files changed

+541
-145
lines changed

6 files changed

+541
-145
lines changed

solution/1600-1699/1670.Design Front Middle Back Queue/README.md

Lines changed: 183 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ q.popFront(); // 返回 -1 -> [] (队列为空)
6464

6565
<!-- 这里可写通用的实现逻辑 -->
6666

67-
两个“双端队列”实现。
67+
**方法一:双“双端队列”**
68+
69+
我们用两个双端队列,其中 $q_1$ 存储前半部分,而 $q_2$ 存储后半部分。每次由 `rebalance` 函数来维护两个队列的平衡性,即保持 $q_1$ 和 $q_2$ 的长度差不超过 $1$ 且 $q_2$ 的长度不小于 $q_1$ 的长度。
70+
71+
时间复杂度方面,每次操作的时间复杂度为 $O(1)$,总的空间复杂度为 $O(n)$。
6872

6973
<!-- tabs:start -->
7074

@@ -75,56 +79,53 @@ q.popFront(); // 返回 -1 -> [] (队列为空)
7579
```python
7680
class FrontMiddleBackQueue:
7781
def __init__(self):
78-
self.left = deque()
79-
self.right = deque()
82+
self.q1 = deque()
83+
self.q2 = deque()
8084

8185
def pushFront(self, val: int) -> None:
82-
self.left.appendleft(val)
86+
self.q1.appendleft(val)
8387
self.rebalance()
8488

8589
def pushMiddle(self, val: int) -> None:
86-
self.left.append(val)
90+
self.q1.append(val)
8791
self.rebalance()
8892

8993
def pushBack(self, val: int) -> None:
90-
self.right.append(val)
94+
self.q2.append(val)
9195
self.rebalance()
9296

9397
def popFront(self) -> int:
94-
if self.empty():
98+
if not self.q1 and not self.q2:
9599
return -1
96-
if self.left:
97-
val = self.left.popleft()
100+
if self.q1:
101+
val = self.q1.popleft()
98102
else:
99-
val = self.right.popleft()
103+
val = self.q2.popleft()
100104
self.rebalance()
101105
return val
102106

103107
def popMiddle(self) -> int:
104-
if self.empty():
108+
if not self.q1 and not self.q2:
105109
return -1
106-
if len(self.left) >= len(self.right):
107-
val = self.left.pop()
110+
if len(self.q1) == len(self.q2):
111+
val = self.q1.pop()
108112
else:
109-
val = self.right.popleft()
113+
val = self.q2.popleft()
110114
self.rebalance()
111115
return val
112116

113117
def popBack(self) -> int:
114-
if self.empty():
118+
if not self.q2:
115119
return -1
116-
val = self.right.pop()
120+
val = self.q2.pop()
117121
self.rebalance()
118122
return val
119123

120-
def empty(self) -> bool:
121-
return not self.left and not self.right
122-
123-
def rebalance(self) -> None:
124-
while len(self.left) > len(self.right):
125-
self.right.appendleft(self.left.pop())
126-
while len(self.right) - len(self.left) > 1:
127-
self.left.append(self.right.popleft())
124+
def rebalance(self):
125+
if len(self.q1) > len(self.q2):
126+
self.q2.appendleft(self.q1.pop())
127+
if len(self.q2) > len(self.q1) + 1:
128+
self.q1.append(self.q2.popleft())
128129

129130

130131
# Your FrontMiddleBackQueue object will be instantiated and called as such:
@@ -143,66 +144,61 @@ class FrontMiddleBackQueue:
143144

144145
```java
145146
class FrontMiddleBackQueue {
146-
private Deque<Integer> left;
147-
private Deque<Integer> right;
147+
private Deque<Integer> q1 = new ArrayDeque<>();
148+
private Deque<Integer> q2 = new ArrayDeque<>();
148149

149150
public FrontMiddleBackQueue() {
150-
left = new LinkedList<>();
151-
right = new LinkedList<>();
151+
152152
}
153153

154154
public void pushFront(int val) {
155-
left.offerFirst(val);
155+
q1.offerFirst(val);
156156
rebalance();
157157
}
158158

159159
public void pushMiddle(int val) {
160-
left.offerLast(val);
160+
q1.offerLast(val);
161161
rebalance();
162162
}
163163

164164
public void pushBack(int val) {
165-
right.offerLast(val);
165+
q2.offerLast(val);
166166
rebalance();
167167
}
168168

169169
public int popFront() {
170-
if (empty()) {
170+
if (q1.isEmpty() && q2.isEmpty()) {
171171
return -1;
172172
}
173-
int val = left.isEmpty() ? right.pollFirst() : left.pollFirst();
173+
int val = q1.isEmpty() ? q2.pollFirst() : q1.pollFirst();
174174
rebalance();
175175
return val;
176176
}
177177

178178
public int popMiddle() {
179-
if (empty()) {
179+
if (q1.isEmpty() && q2.isEmpty()) {
180180
return -1;
181181
}
182-
int val = left.size() >= right.size() ? left.pollLast() : right.pollFirst();
182+
int val = q1.size() == q2.size() ? q1.pollLast() : q2.pollFirst();
183183
rebalance();
184184
return val;
185185
}
186186

187187
public int popBack() {
188-
if (empty()) {
188+
if (q2.isEmpty()) {
189189
return -1;
190190
}
191-
int val = right.pollLast();
191+
int val = q2.pollLast();
192192
rebalance();
193193
return val;
194194
}
195195

196-
private boolean empty() {
197-
return left.isEmpty() && right.isEmpty();
198-
}
199-
200196
private void rebalance() {
201-
while (left.size() > right.size()) {
202-
right.offerFirst(left.pollLast());
197+
if (q1.size() > q2.size()) {
198+
q2.offerFirst(q1.pollLast());
203199
}
204-
while (right.size() - left.size() > 1) {
205-
left.offerLast(right.pollFirst());
200+
if (q2.size() > q1.size() + 1) {
201+
q1.offerLast(q2.pollFirst());
206202
}
207203
}
208204
}
@@ -219,6 +215,148 @@ class FrontMiddleBackQueue {
219215
*/
220216
```
221217

218+
### **C++**
219+
220+
```cpp
221+
class FrontMiddleBackQueue {
222+
public:
223+
FrontMiddleBackQueue() {
224+
225+
}
226+
227+
void pushFront(int val) {
228+
q1.push_front(val);
229+
rebalance();
230+
}
231+
232+
void pushMiddle(int val) {
233+
q1.push_back(val);
234+
rebalance();
235+
}
236+
237+
void pushBack(int val) {
238+
q2.push_back(val);
239+
rebalance();
240+
}
241+
242+
int popFront() {
243+
if (q1.empty() && q2.empty()) return -1;
244+
int val = 0;
245+
if (q1.size()) {
246+
val = q1.front();
247+
q1.pop_front();
248+
} else {
249+
val = q2.front();
250+
q2.pop_front();
251+
}
252+
rebalance();
253+
return val;
254+
}
255+
256+
int popMiddle() {
257+
if (q1.empty() && q2.empty()) return -1;
258+
int val = 0;
259+
if (q1.size() == q2.size()) {
260+
val = q1.back();
261+
q1.pop_back();
262+
} else {
263+
val = q2.front();
264+
q2.pop_front();
265+
}
266+
rebalance();
267+
return val;
268+
}
269+
270+
int popBack() {
271+
if (q2.empty()) return -1;
272+
int val = q2.back();
273+
q2.pop_back();
274+
rebalance();
275+
return val;
276+
}
277+
278+
private:
279+
deque<int> q1;
280+
deque<int> q2;
281+
282+
void rebalance() {
283+
if (q1.size() > q2.size()) {
284+
q2.push_front(q1.back());
285+
q1.pop_back();
286+
}
287+
if (q2.size() > q1.size() + 1) {
288+
q1.push_back(q2.front());
289+
q2.pop_front();
290+
}
291+
}
292+
};
293+
294+
/**
295+
* Your FrontMiddleBackQueue object will be instantiated and called as such:
296+
* FrontMiddleBackQueue* obj = new FrontMiddleBackQueue();
297+
* obj->pushFront(val);
298+
* obj->pushMiddle(val);
299+
* obj->pushBack(val);
300+
* int param_4 = obj->popFront();
301+
* int param_5 = obj->popMiddle();
302+
* int param_6 = obj->popBack();
303+
*/
304+
```
305+
306+
### **Go**
307+
308+
```go
309+
type FrontMiddleBackQueue struct{}
310+
311+
var a []int
312+
313+
func Constructor() (_ FrontMiddleBackQueue) {
314+
a = nil
315+
return
316+
}
317+
318+
func (FrontMiddleBackQueue) PushFront(v int) {
319+
a = append([]int{v}, a...)
320+
}
321+
322+
func (FrontMiddleBackQueue) PushMiddle(v int) {
323+
p := len(a) / 2
324+
a = append(a[:p], append([]int{v}, a[p:]...)...)
325+
}
326+
327+
func (FrontMiddleBackQueue) PushBack(v int) {
328+
a = append(a, v)
329+
}
330+
331+
func (FrontMiddleBackQueue) PopFront() (ans int) {
332+
if len(a) == 0 {
333+
return -1
334+
}
335+
ans = a[0]
336+
a = a[1:]
337+
return
338+
}
339+
340+
func (FrontMiddleBackQueue) PopMiddle() (ans int) {
341+
if len(a) == 0 {
342+
return -1
343+
}
344+
p := (len(a) - 1) / 2
345+
ans = a[p]
346+
a = append(a[:p], a[p+1:]...)
347+
return
348+
}
349+
350+
func (FrontMiddleBackQueue) PopBack() (ans int) {
351+
if len(a) == 0 {
352+
return -1
353+
}
354+
ans = a[len(a)-1]
355+
a = a[:len(a)-1]
356+
return
357+
}
358+
```
359+
222360
### **JavaScript**
223361

224362
```js

0 commit comments

Comments
 (0)