@@ -64,7 +64,11 @@ q.popFront(); // 返回 -1 -> [] (队列为空)
64
64
65
65
<!-- 这里可写通用的实现逻辑 -->
66
66
67
- 两个“双端队列”实现。
67
+ ** 方法一:双“双端队列”**
68
+
69
+ 我们用两个双端队列,其中 $q_1$ 存储前半部分,而 $q_2$ 存储后半部分。每次由 ` rebalance ` 函数来维护两个队列的平衡性,即保持 $q_1$ 和 $q_2$ 的长度差不超过 $1$ 且 $q_2$ 的长度不小于 $q_1$ 的长度。
70
+
71
+ 时间复杂度方面,每次操作的时间复杂度为 $O(1)$,总的空间复杂度为 $O(n)$。
68
72
69
73
<!-- tabs:start -->
70
74
@@ -75,56 +79,53 @@ q.popFront(); // 返回 -1 -> [] (队列为空)
75
79
``` python
76
80
class FrontMiddleBackQueue :
77
81
def __init__ (self ):
78
- self .left = deque()
79
- self .right = deque()
82
+ self .q1 = deque()
83
+ self .q2 = deque()
80
84
81
85
def pushFront (self , val : int ) -> None :
82
- self .left .appendleft(val)
86
+ self .q1 .appendleft(val)
83
87
self .rebalance()
84
88
85
89
def pushMiddle (self , val : int ) -> None :
86
- self .left .append(val)
90
+ self .q1 .append(val)
87
91
self .rebalance()
88
92
89
93
def pushBack (self , val : int ) -> None :
90
- self .right .append(val)
94
+ self .q2 .append(val)
91
95
self .rebalance()
92
96
93
97
def popFront (self ) -> int :
94
- if self .empty() :
98
+ if not self .q1 and not self .q2 :
95
99
return - 1
96
- if self .left :
97
- val = self .left .popleft()
100
+ if self .q1 :
101
+ val = self .q1 .popleft()
98
102
else :
99
- val = self .right .popleft()
103
+ val = self .q2 .popleft()
100
104
self .rebalance()
101
105
return val
102
106
103
107
def popMiddle (self ) -> int :
104
- if self .empty() :
108
+ if not self .q1 and not self .q2 :
105
109
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()
108
112
else :
109
- val = self .right .popleft()
113
+ val = self .q2 .popleft()
110
114
self .rebalance()
111
115
return val
112
116
113
117
def popBack (self ) -> int :
114
- if self .empty() :
118
+ if not self .q2 :
115
119
return - 1
116
- val = self .right .pop()
120
+ val = self .q2 .pop()
117
121
self .rebalance()
118
122
return val
119
123
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())
128
129
129
130
130
131
# Your FrontMiddleBackQueue object will be instantiated and called as such:
@@ -143,66 +144,61 @@ class FrontMiddleBackQueue:
143
144
144
145
``` java
145
146
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<> () ;
148
149
149
150
public FrontMiddleBackQueue () {
150
- left = new LinkedList<> ();
151
- right = new LinkedList<> ();
151
+
152
152
}
153
153
154
154
public void pushFront (int val ) {
155
- left . offerFirst(val);
155
+ q1 . offerFirst(val);
156
156
rebalance();
157
157
}
158
158
159
159
public void pushMiddle (int val ) {
160
- left . offerLast(val);
160
+ q1 . offerLast(val);
161
161
rebalance();
162
162
}
163
163
164
164
public void pushBack (int val ) {
165
- right . offerLast(val);
165
+ q2 . offerLast(val);
166
166
rebalance();
167
167
}
168
168
169
169
public int popFront () {
170
- if (empty ()) {
170
+ if (q1 . isEmpty() && q2 . isEmpty ()) {
171
171
return - 1 ;
172
172
}
173
- int val = left . isEmpty() ? right . pollFirst() : left . pollFirst();
173
+ int val = q1 . isEmpty() ? q2 . pollFirst() : q1 . pollFirst();
174
174
rebalance();
175
175
return val;
176
176
}
177
177
178
178
public int popMiddle () {
179
- if (empty ()) {
179
+ if (q1 . isEmpty() && q2 . isEmpty ()) {
180
180
return - 1 ;
181
181
}
182
- int val = left . size() >= right . size() ? left . pollLast() : right . pollFirst();
182
+ int val = q1 . size() == q2 . size() ? q1 . pollLast() : q2 . pollFirst();
183
183
rebalance();
184
184
return val;
185
185
}
186
186
187
187
public int popBack () {
188
- if (empty ()) {
188
+ if (q2 . isEmpty ()) {
189
189
return - 1 ;
190
190
}
191
- int val = right . pollLast();
191
+ int val = q2 . pollLast();
192
192
rebalance();
193
193
return val;
194
194
}
195
195
196
- private boolean empty () {
197
- return left. isEmpty() && right. isEmpty();
198
- }
199
-
200
196
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());
203
199
}
204
- while (right . size() - left . size() > 1 ) {
205
- left . offerLast(right . pollFirst());
200
+ if (q2 . size() > q1 . size() + 1 ) {
201
+ q1 . offerLast(q2 . pollFirst());
206
202
}
207
203
}
208
204
}
@@ -219,6 +215,148 @@ class FrontMiddleBackQueue {
219
215
*/
220
216
```
221
217
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
+
222
360
### ** JavaScript**
223
361
224
362
``` js
0 commit comments