@@ -53,7 +53,11 @@ mRUQueue.fetch(8); // 第 8 个元素 (2) 已经在队列尾部了,所以直
53
53
54
54
** 方法一:树状数组 + 二分查找**
55
55
56
+ 我们用一个数组 $q$ 维护当前队列中的元素,移动第 $k$ 个元素时,我们考虑不删除该元素,而是直接将其追加到数组末尾。如果不删除,我们如何知道第 $k$ 个元素在数组 $q$ 中的位置呢?
56
57
58
+ 我们可以用一个树状数组维护数组 $q$ 中每个位置的元素是否被删除,如果第 $i$ 个位置的元素被删除,那么我们更新树状数组中的第 $i$ 个位置,表示该位置被移动的次数增加 $1$。这样,我们每次要删除第 $k$ 个元素时,可以用二分查找,找到第一个满足 $i - tree.query(i) \geq k$ 的位置 $i$,即为第 $k$ 个元素在数组 $q$ 中的位置。不妨记 $x=q[ i] $,那么我们将 $x$ 追加到数组 $q$ 的末尾,同时更新树状数组中第 $i$ 个位置的值,表示该位置被移动的次数增加 $1$。最后,我们返回 $x$ 即可。
59
+
60
+ 时间复杂度 $(\log ^2 n)$,空间复杂度 $O(n)$。其中 $n$ 为队列的长度。
57
61
58
62
<!-- tabs:start -->
59
63
@@ -80,44 +84,41 @@ class MRUQueue:
80
84
81
85
``` python
82
86
class BinaryIndexedTree :
83
- def __init__ (self , n ):
87
+ def __init__ (self , n : int ):
84
88
self .n = n
85
89
self .c = [0 ] * (n + 1 )
86
90
87
- @ staticmethod
88
- def lowbit (x ):
89
- return x & - x
90
-
91
- def update (self , x , delta ):
91
+ def update (self , x : int , v : int ):
92
92
while x <= self .n:
93
- self .c[x] += delta
94
- x += BinaryIndexedTree.lowbit(x)
93
+ self .c[x] += v
94
+ x += x & - x
95
95
96
- def query (self , x ) :
96
+ def query (self , x : int ) -> int :
97
97
s = 0
98
- while x > 0 :
98
+ while x:
99
99
s += self .c[x]
100
- x -= BinaryIndexedTree.lowbit(x)
100
+ x -= x & - x
101
101
return s
102
102
103
103
104
104
class MRUQueue :
105
+
105
106
def __init__ (self , n : int ):
106
- self .data = list (range (n + 1 ))
107
+ self .q = list (range (n + 1 ))
107
108
self .tree = BinaryIndexedTree(n + 2010 )
108
109
109
110
def fetch (self , k : int ) -> int :
110
- left, right = 1 , len (self .data )
111
- while left < right :
112
- mid = (left + right ) >> 1
111
+ l, r = 1 , len (self .q )
112
+ while l < r :
113
+ mid = (l + r ) >> 1
113
114
if mid - self .tree.query(mid) >= k:
114
- right = mid
115
+ r = mid
115
116
else :
116
- left = mid + 1
117
- self .data.append( self .data[left])
118
- self .tree.update(left, 1 )
119
- return self .data[left]
120
-
117
+ l = mid + 1
118
+ x = self .q[l]
119
+ self .q.append(x )
120
+ self .tree.update(l, 1 )
121
+ return x
121
122
122
123
# Your MRUQueue object will be instantiated and called as such:
123
124
# obj = MRUQueue(n)
@@ -135,58 +136,54 @@ class BinaryIndexedTree {
135
136
136
137
public BinaryIndexedTree (int n ) {
137
138
this . n = n;
138
- c = new int [n + 1 ];
139
+ this . c = new int [n + 1 ];
139
140
}
140
141
141
- public void update (int x , int delta ) {
142
+ public void update (int x , int v ) {
142
143
while (x <= n) {
143
- c[x] += delta ;
144
- x += lowbit(x) ;
144
+ c[x] += v ;
145
+ x += x & - x ;
145
146
}
146
147
}
147
148
148
149
public int query (int x ) {
149
150
int s = 0 ;
150
151
while (x > 0 ) {
151
152
s += c[x];
152
- x -= lowbit(x) ;
153
+ x -= x & - x ;
153
154
}
154
155
return s;
155
156
}
156
-
157
- public static int lowbit (int x ) {
158
- return x & - x;
159
- }
160
157
}
161
158
162
159
class MRUQueue {
163
160
private int n;
164
- private int [] data ;
161
+ private int [] q ;
165
162
private BinaryIndexedTree tree;
166
163
167
164
public MRUQueue (int n ) {
168
165
this . n = n;
169
- data = new int [n + 2010 ];
166
+ q = new int [n + 2010 ];
170
167
for (int i = 1 ; i <= n; ++ i) {
171
- data [i] = i;
168
+ q [i] = i;
172
169
}
173
170
tree = new BinaryIndexedTree (n + 2010 );
174
171
}
175
172
176
173
public int fetch (int k ) {
177
- int left = 1 ;
178
- int right = n++ ;
179
- while (left < right) {
180
- int mid = (left + right) >> 1 ;
174
+ int l = 1 , r = n;
175
+ while (l < r) {
176
+ int mid = (l + r) >> 1 ;
181
177
if (mid - tree. query(mid) >= k) {
182
- right = mid;
178
+ r = mid;
183
179
} else {
184
- left = mid + 1 ;
180
+ l = mid + 1 ;
185
181
}
186
182
}
187
- data[n] = data[left];
188
- tree. update(left, 1 );
189
- return data[left];
183
+ int x = q[l];
184
+ q[++ n] = x;
185
+ tree. update(l, 1 );
186
+ return x;
190
187
}
191
188
}
192
189
@@ -202,60 +199,58 @@ class MRUQueue {
202
199
``` cpp
203
200
class BinaryIndexedTree {
204
201
public:
205
- int n;
206
- vector<int > c;
207
-
208
202
BinaryIndexedTree(int _ n)
209
203
: n(_ n)
210
- , c(_n + 1) { }
204
+ , c(_ n + 1) {}
211
205
212
206
void update(int x, int delta) {
213
207
while (x <= n) {
214
208
c[x] += delta;
215
- x += lowbit(x) ;
209
+ x += x & -x ;
216
210
}
217
211
}
218
212
219
213
int query (int x) {
220
214
int s = 0;
221
- while (x > 0 ) {
215
+ while (x) {
222
216
s += c[ x] ;
223
- x -= lowbit(x) ;
217
+ x -= x & -x ;
224
218
}
225
219
return s;
226
220
}
227
221
228
- int lowbit(int x) {
229
- return x & -x ;
230
- }
222
+ private:
223
+ int n ;
224
+ vector< int > c;
231
225
};
232
226
233
227
class MRUQueue {
234
228
public:
235
- int n;
236
- vector<int > data;
237
- BinaryIndexedTree* tree;
238
-
239
229
MRUQueue(int n) {
240
- this->n = n;
241
- data.resize(n + 1);
242
- for (int i = 1; i <= n; ++i) data[i] = i;
230
+ q.resize(n + 1);
231
+ iota(q.begin() + 1, q.end(), 1);
243
232
tree = new BinaryIndexedTree(n + 2010);
244
233
}
245
234
246
235
int fetch(int k) {
247
- int left = 1, right = data.size();
248
- while (left < right) {
249
- int mid = (left + right) >> 1;
250
- if (mid - tree->query(mid) >= k)
251
- right = mid;
252
- else
253
- left = mid + 1;
236
+ int l = 1, r = q.size();
237
+ while (l < r) {
238
+ int mid = (l + r) >> 1;
239
+ if (mid - tree->query(mid) >= k) {
240
+ r = mid;
241
+ } else {
242
+ l = mid + 1;
243
+ }
254
244
}
255
- data.push_back(data[left]);
256
- tree->update(left, 1);
257
- return data[left];
245
+ int x = q[l];
246
+ q.push_back(x);
247
+ tree->update(l, 1);
248
+ return x;
258
249
}
250
+
251
+ private:
252
+ vector<int > q;
253
+ BinaryIndexedTree* tree;
259
254
};
260
255
261
256
/**
@@ -278,52 +273,49 @@ func newBinaryIndexedTree(n int) *BinaryIndexedTree {
278
273
return &BinaryIndexedTree{n, c}
279
274
}
280
275
281
- func (this *BinaryIndexedTree) lowbit(x int) int {
282
- return x & -x
283
- }
284
-
285
276
func (this *BinaryIndexedTree) update(x, delta int) {
286
277
for x <= this.n {
287
278
this.c[x] += delta
288
- x += this.lowbit(x)
279
+ x += x & -x
289
280
}
290
281
}
291
282
292
283
func (this *BinaryIndexedTree) query(x int) int {
293
284
s := 0
294
285
for x > 0 {
295
286
s += this.c[x]
296
- x -= this.lowbit(x)
287
+ x -= x & -x
297
288
}
298
289
return s
299
290
}
300
291
301
292
type MRUQueue struct {
302
- data []int
293
+ q []int
303
294
tree *BinaryIndexedTree
304
295
}
305
296
306
297
func Constructor(n int) MRUQueue {
307
- data := make([]int, n+1)
308
- for i := range data {
309
- data [i] = i
298
+ q := make([]int, n+1)
299
+ for i := 1; i <= n; i++ {
300
+ q [i] = i
310
301
}
311
- return MRUQueue{data , newBinaryIndexedTree(n + 2010)}
302
+ return MRUQueue{q , newBinaryIndexedTree(n + 2010)}
312
303
}
313
304
314
305
func (this *MRUQueue) Fetch(k int) int {
315
- left, right := 1, len(this.data )
316
- for left < right {
317
- mid := (left + right ) >> 1
306
+ l, r := 1, len(this.q )
307
+ for l < r {
308
+ mid := (l + r ) >> 1
318
309
if mid-this.tree.query(mid) >= k {
319
- right = mid
310
+ r = mid
320
311
} else {
321
- left = mid + 1
312
+ l = mid + 1
322
313
}
323
314
}
324
- this.data = append(this.data, this.data[left])
325
- this.tree.update(left, 1)
326
- return this.data[left]
315
+ x := this.q[l]
316
+ this.q = append(this.q, x)
317
+ this.tree.update(l, 1)
318
+ return x
327
319
}
328
320
329
321
/**
@@ -333,6 +325,72 @@ func (this *MRUQueue) Fetch(k int) int {
333
325
*/
334
326
```
335
327
328
+ ### ** TypeScript**
329
+
330
+ ``` ts
331
+ class BinaryIndexedTree {
332
+ private n: number ;
333
+ private c: number [];
334
+
335
+ constructor (n : number ) {
336
+ this .n = n ;
337
+ this .c = new Array (n + 1 ).fill (0 );
338
+ }
339
+
340
+ public update(x : number , v : number ): void {
341
+ while (x <= this .n ) {
342
+ this .c [x ] += v ;
343
+ x += x & - x ;
344
+ }
345
+ }
346
+
347
+ public query(x : number ): number {
348
+ let s = 0 ;
349
+ while (x > 0 ) {
350
+ s += this .c [x ];
351
+ x -= x & - x ;
352
+ }
353
+ return s ;
354
+ }
355
+ }
356
+
357
+ class MRUQueue {
358
+ private q: number [];
359
+ private tree: BinaryIndexedTree ;
360
+
361
+ constructor (n : number ) {
362
+ this .q = new Array (n + 1 );
363
+ for (let i = 1 ; i <= n ; ++ i ) {
364
+ this .q [i ] = i ;
365
+ }
366
+ this .tree = new BinaryIndexedTree (n + 2010 );
367
+ }
368
+
369
+ fetch(k : number ): number {
370
+ let l = 1 ;
371
+ let r = this .q .length ;
372
+ while (l < r ) {
373
+ const mid = (l + r ) >> 1 ;
374
+ if (mid - this .tree .query (mid ) >= k ) {
375
+ r = mid ;
376
+ } else {
377
+ l = mid + 1 ;
378
+ }
379
+ }
380
+ const x = this .q [l ];
381
+ this .q .push (x );
382
+ this .tree .update (l , 1 );
383
+ return x ;
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Your MRUQueue object will be instantiated and called as such:
389
+ * var obj = new MRUQueue(n)
390
+ * var param_1 = obj.fetch(k)
391
+ */
392
+ ```
393
+
336
394
### ** ...**
337
395
338
396
```
0 commit comments