@@ -67,22 +67,373 @@ obj.calculateMKAverage(); // 最后 3 个元素为 [5,5,5]
67
67
68
68
<!-- 这里可写通用的实现逻辑 -->
69
69
70
+ ** 方法一:有序集合 + 队列**
71
+
72
+ 在本题中,我们需要维护的数据结构或变量有:
73
+
74
+ - 一个长度为 $m$ 的队列 $q$,其中队首元素为最早加入的元素,队尾元素为最近加入的元素
75
+ - 三个有序集合,分别为 $lo$, $mid$, $hi$,其中 $lo$ 和 $hi$ 分别存储最小的 $k$ 个元素和最大的 $k$ 个元素,而 $mid$ 存储剩余的元素;
76
+ - 一个变量 $s$,维护 $mid$ 中所有元素的和。
77
+ - 部分编程语言(如 Java, Go)额外维护两个变量 $size1$ 和 $size3$,分别表示 $lo$ 和 $hi$ 中元素的个数。
78
+
79
+ 调用 $addElement(num)$ 函数时,顺序执行以下操作:
80
+
81
+ 1 . 如果 $lo$ 为空,或者 $num \leq max(lo)$,则将 $num$ 加入 $lo$ 中;否则如果 $hi$ 为空,或者 $num \geq min(hi)$,则将 $num$ 加入 $hi$ 中;否则将 $num$ 加入 $mid$ 中,同时将 $num$ 的值加到 $s$ 中。
82
+ 1 . 接下来将 $num$ 加入队列 $q$ 中,如果此时队列 $q$ 的长度大于 $m$,则将队首元素 $x$ 从队列 $q$ 中移除,接下来从 $lo$, $mid$ 或 $hi$ 中选择其中一个包含 $x$ 的集合,将 $x$ 从该集合中移除,如果该集合为 $mid$,则将 $s$ 减去 $x$ 的值。
83
+ 1 . 如果 $lo$ 的长度大于 $k$,则循环将 $lo$ 中的最大值 $max(lo)$ 从 $lo$ 中移除,将 $max(lo)$ 加入 $mid$ 中,同时将 $s$ 加上 $max(lo)$ 的值。
84
+ 1 . 如果 $hi$ 的长度大于 $k$,则循环将 $hi$ 中的最小值 $min(hi)$ 从 $hi$ 中移除,将 $min(hi)$ 加入 $mid$ 中,同时将 $s$ 加上 $min(hi)$ 的值。
85
+ 1 . 如果 $lo$ 的长度小于 $k$,并且 $mid$ 不为空,则循环将 $mid$ 中的最小值 $min(mid)$ 从 $mid$ 中移除,将 $min(mid)$ 加入 $lo$ 中,同时将 $s$ 减去 $min(mid)$ 的值。
86
+ 1 . 如果 $hi$ 的长度小于 $k$,并且 $mid$ 不为空,则循环将 $mid$ 中的最大值 $max(mid)$ 从 $mid$ 中移除,将 $max(mid)$ 加入 $hi$ 中,同时将 $s$ 减去 $max(mid)$ 的值。
87
+
88
+ 调用 $calculateMKAverage()$ 函数时,如果 $q$ 的长度小于 $m$,则返回 $-1$,否则返回 $\frac{s}{m - 2k}$。
89
+
90
+ 时间复杂度方面,每次调用 $addElement(num)$ 函数的时间复杂度为 $O(\log m)$,每次调用 $calculateMKAverage()$ 函数的时间复杂度为 $O(1)$。空间复杂度为 $O(m)$。
91
+
70
92
<!-- tabs:start -->
71
93
72
94
### ** Python3**
73
95
74
96
<!-- 这里可写当前语言的特殊实现逻辑 -->
75
97
76
98
``` python
99
+ from sortedcontainers import SortedList
100
+
101
+
102
+ class MKAverage :
77
103
104
+ def __init__ (self , m : int , k : int ):
105
+ self .m = m
106
+ self .k = k
107
+ self .s = 0
108
+ self .q = deque()
109
+ self .lo = SortedList()
110
+ self .mid = SortedList()
111
+ self .hi = SortedList()
112
+
113
+ def addElement (self , num : int ) -> None :
114
+ if not self .lo or num <= self .lo[- 1 ]:
115
+ self .lo.add(num)
116
+ elif not self .hi or num >= self .hi[0 ]:
117
+ self .hi.add(num)
118
+ else :
119
+ self .mid.add(num)
120
+ self .s += num
121
+ self .q.append(num)
122
+ if len (self .q) > self .m:
123
+ x = self .q.popleft()
124
+ if x in self .lo:
125
+ self .lo.remove(x)
126
+ elif x in self .hi:
127
+ self .hi.remove(x)
128
+ else :
129
+ self .mid.remove(x)
130
+ self .s -= x
131
+ while len (self .lo) > self .k:
132
+ x = self .lo.pop()
133
+ self .mid.add(x)
134
+ self .s += x
135
+ while len (self .hi) > self .k:
136
+ x = self .hi.pop(0 )
137
+ self .mid.add(x)
138
+ self .s += x
139
+ while len (self .lo) < self .k and self .mid:
140
+ x = self .mid.pop(0 )
141
+ self .lo.add(x)
142
+ self .s -= x
143
+ while len (self .hi) < self .k and self .mid:
144
+ x = self .mid.pop()
145
+ self .hi.add(x)
146
+ self .s -= x
147
+
148
+ def calculateMKAverage (self ) -> int :
149
+ return - 1 if len (self .q) < self .m else self .s // (self .m - 2 * self .k)
150
+
151
+
152
+ # Your MKAverage object will be instantiated and called as such:
153
+ # obj = MKAverage(m, k)
154
+ # obj.addElement(num)
155
+ # param_2 = obj.calculateMKAverage()
78
156
```
79
157
80
158
### ** Java**
81
159
82
160
<!-- 这里可写当前语言的特殊实现逻辑 -->
83
161
84
162
``` java
163
+ class MKAverage {
164
+
165
+ private int m, k;
166
+ private long s;
167
+ private int size1, size3;
168
+ private Deque<Integer > q = new ArrayDeque<> ();
169
+ private TreeMap<Integer , Integer > lo = new TreeMap<> ();
170
+ private TreeMap<Integer , Integer > mid = new TreeMap<> ();
171
+ private TreeMap<Integer , Integer > hi = new TreeMap<> ();
172
+
173
+
174
+ public MKAverage (int m , int k ) {
175
+ this . m = m;
176
+ this . k = k;
177
+ }
178
+
179
+ public void addElement (int num ) {
180
+ if (lo. isEmpty() || num <= lo. lastKey()) {
181
+ lo. merge(num, 1 , Integer :: sum);
182
+ ++ size1;
183
+ } else if (hi. isEmpty() || num >= hi. firstKey()) {
184
+ hi. merge(num, 1 , Integer :: sum);
185
+ ++ size3;
186
+ } else {
187
+ mid. merge(num, 1 , Integer :: sum);
188
+ s += num;
189
+ }
190
+ q. offer(num);
191
+ if (q. size() > m) {
192
+ int x = q. poll();
193
+ if (lo. containsKey(x)) {
194
+ lo. merge(x, - 1 , Integer :: sum);
195
+ if (lo. get(x) == 0 ) {
196
+ lo. remove(x);
197
+ }
198
+ -- size1;
199
+ } else if (hi. containsKey(x)) {
200
+ hi. merge(x, - 1 , Integer :: sum);
201
+ if (hi. get(x) == 0 ) {
202
+ hi. remove(x);
203
+ }
204
+ -- size3;
205
+ } else {
206
+ mid. merge(x, - 1 , Integer :: sum);
207
+ if (mid. get(x) == 0 ) {
208
+ mid. remove(x);
209
+ }
210
+ s -= x;
211
+ }
212
+ }
213
+ for (; size1 > k; -- size1) {
214
+ int x = lo. lastKey();
215
+ lo. merge(x, - 1 , Integer :: sum);
216
+ if (lo. get(x) == 0 ) {
217
+ lo. remove(x);
218
+ }
219
+ mid. merge(x, 1 , Integer :: sum);
220
+ s += x;
221
+ }
222
+ for (; size3 > k; -- size3) {
223
+ int x = hi. firstKey();
224
+ hi. merge(x, - 1 , Integer :: sum);
225
+ if (hi. get(x) == 0 ) {
226
+ hi. remove(x);
227
+ }
228
+ mid. merge(x, 1 , Integer :: sum);
229
+ s += x;
230
+ }
231
+ for (; size1 < k && ! mid. isEmpty(); ++ size1) {
232
+ int x = mid. firstKey();
233
+ mid. merge(x, - 1 , Integer :: sum);
234
+ if (mid. get(x) == 0 ) {
235
+ mid. remove(x);
236
+ }
237
+ s -= x;
238
+ lo. merge(x, 1 , Integer :: sum);
239
+ }
240
+ for (; size3 < k && ! mid. isEmpty(); ++ size3) {
241
+ int x = mid. lastKey();
242
+ mid. merge(x, - 1 , Integer :: sum);
243
+ if (mid. get(x) == 0 ) {
244
+ mid. remove(x);
245
+ }
246
+ s -= x;
247
+ hi. merge(x, 1 , Integer :: sum);
248
+ }
249
+ }
250
+
251
+ public int calculateMKAverage () {
252
+ return q. size() < m ? - 1 : (int ) (s / (q. size() - k * 2 ));
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Your MKAverage object will be instantiated and called as such:
258
+ * MKAverage obj = new MKAverage(m, k);
259
+ * obj.addElement(num);
260
+ * int param_2 = obj.calculateMKAverage();
261
+ */
262
+ ```
263
+
264
+ ### ** C++**
265
+
266
+ ``` cpp
267
+ class MKAverage {
268
+ public:
269
+ MKAverage(int m, int k) {
270
+ this->m = m;
271
+ this->k = k;
272
+ }
273
+
274
+ void addElement(int num) {
275
+ if (lo.empty() || num <= *lo.rbegin()) {
276
+ lo.insert(num);
277
+ } else if (hi.empty() || num >= *hi.begin()) {
278
+ hi.insert(num);
279
+ } else {
280
+ mid.insert(num);
281
+ s += num;
282
+ }
283
+
284
+ q.push(num);
285
+ if (q.size() > m) {
286
+ int x = q.front();
287
+ q.pop();
288
+ if (lo.find(x) != lo.end()) {
289
+ lo.erase(lo.find(x));
290
+ } else if (hi.find(x) != hi.end()) {
291
+ hi.erase(hi.find(x));
292
+ } else {
293
+ mid.erase(mid.find(x));
294
+ s -= x;
295
+ }
296
+ }
297
+ while (lo.size() > k) {
298
+ int x = *lo.rbegin();
299
+ lo.erase(prev(lo.end()));
300
+ mid.insert(x);
301
+ s += x;
302
+ }
303
+ while (hi.size() > k) {
304
+ int x = *hi.begin();
305
+ hi.erase(hi.begin());
306
+ mid.insert(x);
307
+ s += x;
308
+ }
309
+ while (lo.size() < k && mid.size()) {
310
+ int x = *mid.begin();
311
+ mid.erase(mid.begin());
312
+ s -= x;
313
+ lo.insert(x);
314
+ }
315
+ while (hi.size() < k && mid.size()) {
316
+ int x = *mid.rbegin();
317
+ mid.erase(prev(mid.end()));
318
+ s -= x;
319
+ hi.insert(x);
320
+ }
321
+ }
322
+
323
+ int calculateMKAverage() {
324
+ return q.size() < m ? -1 : s / (q.size() - k * 2);
325
+ }
326
+
327
+ private:
328
+ int m, k;
329
+ long long s = 0;
330
+ queue<int > q;
331
+ multiset<int > lo, mid, hi;
332
+ };
333
+
334
+ /* *
335
+ * Your MKAverage object will be instantiated and called as such:
336
+ * MKAverage* obj = new MKAverage(m, k);
337
+ * obj->addElement(num);
338
+ * int param_2 = obj->calculateMKAverage();
339
+ */
340
+ ```
341
+
342
+ ### ** Go**
343
+
344
+ ``` go
345
+ type MKAverage struct {
346
+ lo, mid, hi *redblacktree.Tree
347
+ q []int
348
+ m, k, s int
349
+ size1, size3 int
350
+ }
351
+
352
+ func Constructor (m int , k int ) MKAverage {
353
+ lo := redblacktree.NewWithIntComparator ()
354
+ mid := redblacktree.NewWithIntComparator ()
355
+ hi := redblacktree.NewWithIntComparator ()
356
+ return MKAverage{lo, mid, hi, []int {}, m, k, 0 , 0 , 0 }
357
+ }
358
+
359
+ func (this *MKAverage ) AddElement (num int ) {
360
+ merge := func (rbt *redblacktree.Tree , key, value int ) {
361
+ if v , ok := rbt.Get (key); ok {
362
+ nxt := v.(int ) + value
363
+ if nxt == 0 {
364
+ rbt.Remove (key)
365
+ } else {
366
+ rbt.Put (key, nxt)
367
+ }
368
+ } else {
369
+ rbt.Put (key, value)
370
+ }
371
+ }
372
+
373
+ if this.lo .Empty () || num <= this.lo .Right ().Key .(int ) {
374
+ merge (this.lo , num, 1 )
375
+ this.size1 ++
376
+ } else if this.hi .Empty () || num >= this.hi .Left ().Key .(int ) {
377
+ merge (this.hi , num, 1 )
378
+ this.size3 ++
379
+ } else {
380
+ merge (this.mid , num, 1 )
381
+ this.s += num
382
+ }
383
+ this.q = append (this.q , num)
384
+ if len (this.q ) > this.m {
385
+ x := this.q [0 ]
386
+ this.q = this.q [1 :]
387
+ if _ , ok := this.lo .Get (x); ok {
388
+ merge (this.lo , x, -1 )
389
+ this.size1 --
390
+ } else if _ , ok := this.hi .Get (x); ok {
391
+ merge (this.hi , x, -1 )
392
+ this.size3 --
393
+ } else {
394
+ merge (this.mid , x, -1 )
395
+ this.s -= x
396
+ }
397
+ }
398
+ for ; this.size1 > this.k ; this.size1 -- {
399
+ x := this.lo .Right ().Key .(int )
400
+ merge (this.lo , x, -1 )
401
+ merge (this.mid , x, 1 )
402
+ this.s += x
403
+ }
404
+ for ; this.size3 > this.k ; this.size3 -- {
405
+ x := this.hi .Left ().Key .(int )
406
+ merge (this.hi , x, -1 )
407
+ merge (this.mid , x, 1 )
408
+ this.s += x
409
+ }
410
+ for ; this.size1 < this.k && !this.mid .Empty (); this.size1 ++ {
411
+ x := this.mid .Left ().Key .(int )
412
+ merge (this.mid , x, -1 )
413
+ this.s -= x
414
+ merge (this.lo , x, 1 )
415
+ }
416
+ for ; this.size3 < this.k && !this.mid .Empty (); this.size3 ++ {
417
+ x := this.mid .Right ().Key .(int )
418
+ merge (this.mid , x, -1 )
419
+ this.s -= x
420
+ merge (this.hi , x, 1 )
421
+ }
422
+ }
423
+
424
+ func (this *MKAverage ) CalculateMKAverage () int {
425
+ if len (this.q ) < this.m {
426
+ return -1
427
+ }
428
+ return this.s / (this.m - 2 *this.k )
429
+ }
85
430
431
+ /* *
432
+ * Your MKAverage object will be instantiated and called as such:
433
+ * obj := Constructor(m, k);
434
+ * obj.AddElement(num);
435
+ * param_2 := obj.CalculateMKAverage();
436
+ */
86
437
```
87
438
88
439
### ** ...**
0 commit comments