Skip to content

Commit 79125f4

Browse files
committed
feat: add solutions to lc problem: No.1756
No.1756.Design Most Recently Used Queue
1 parent cea5ac3 commit 79125f4

File tree

7 files changed

+424
-263
lines changed

7 files changed

+424
-263
lines changed

solution/1700-1799/1756.Design Most Recently Used Queue/README.md

+146-88
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ mRUQueue.fetch(8); // 第 8 个元素 (2) 已经在队列尾部了,所以直
5353

5454
**方法一:树状数组 + 二分查找**
5555

56+
我们用一个数组 $q$ 维护当前队列中的元素,移动第 $k$ 个元素时,我们考虑不删除该元素,而是直接将其追加到数组末尾。如果不删除,我们如何知道第 $k$ 个元素在数组 $q$ 中的位置呢?
5657

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$ 为队列的长度。
5761

5862
<!-- tabs:start -->
5963

@@ -80,44 +84,41 @@ class MRUQueue:
8084

8185
```python
8286
class BinaryIndexedTree:
83-
def __init__(self, n):
87+
def __init__(self, n: int):
8488
self.n = n
8589
self.c = [0] * (n + 1)
8690

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):
9292
while x <= self.n:
93-
self.c[x] += delta
94-
x += BinaryIndexedTree.lowbit(x)
93+
self.c[x] += v
94+
x += x & -x
9595

96-
def query(self, x):
96+
def query(self, x: int) -> int:
9797
s = 0
98-
while x > 0:
98+
while x:
9999
s += self.c[x]
100-
x -= BinaryIndexedTree.lowbit(x)
100+
x -= x & -x
101101
return s
102102

103103

104104
class MRUQueue:
105+
105106
def __init__(self, n: int):
106-
self.data = list(range(n + 1))
107+
self.q = list(range(n + 1))
107108
self.tree = BinaryIndexedTree(n + 2010)
108109

109110
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
113114
if mid - self.tree.query(mid) >= k:
114-
right = mid
115+
r = mid
115116
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
121122

122123
# Your MRUQueue object will be instantiated and called as such:
123124
# obj = MRUQueue(n)
@@ -135,58 +136,54 @@ class BinaryIndexedTree {
135136

136137
public BinaryIndexedTree(int n) {
137138
this.n = n;
138-
c = new int[n + 1];
139+
this.c = new int[n + 1];
139140
}
140141

141-
public void update(int x, int delta) {
142+
public void update(int x, int v) {
142143
while (x <= n) {
143-
c[x] += delta;
144-
x += lowbit(x);
144+
c[x] += v;
145+
x += x & -x;
145146
}
146147
}
147148

148149
public int query(int x) {
149150
int s = 0;
150151
while (x > 0) {
151152
s += c[x];
152-
x -= lowbit(x);
153+
x -= x & -x;
153154
}
154155
return s;
155156
}
156-
157-
public static int lowbit(int x) {
158-
return x & -x;
159-
}
160157
}
161158

162159
class MRUQueue {
163160
private int n;
164-
private int[] data;
161+
private int[] q;
165162
private BinaryIndexedTree tree;
166163

167164
public MRUQueue(int n) {
168165
this.n = n;
169-
data = new int[n + 2010];
166+
q = new int[n + 2010];
170167
for (int i = 1; i <= n; ++i) {
171-
data[i] = i;
168+
q[i] = i;
172169
}
173170
tree = new BinaryIndexedTree(n + 2010);
174171
}
175172

176173
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;
181177
if (mid - tree.query(mid) >= k) {
182-
right = mid;
178+
r = mid;
183179
} else {
184-
left = mid + 1;
180+
l = mid + 1;
185181
}
186182
}
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;
190187
}
191188
}
192189

@@ -202,60 +199,58 @@ class MRUQueue {
202199
```cpp
203200
class BinaryIndexedTree {
204201
public:
205-
int n;
206-
vector<int> c;
207-
208202
BinaryIndexedTree(int _n)
209203
: n(_n)
210-
, c(_n + 1) { }
204+
, c(_n + 1) {}
211205

212206
void update(int x, int delta) {
213207
while (x <= n) {
214208
c[x] += delta;
215-
x += lowbit(x);
209+
x += x & -x;
216210
}
217211
}
218212

219213
int query(int x) {
220214
int s = 0;
221-
while (x > 0) {
215+
while (x) {
222216
s += c[x];
223-
x -= lowbit(x);
217+
x -= x & -x;
224218
}
225219
return s;
226220
}
227221

228-
int lowbit(int x) {
229-
return x & -x;
230-
}
222+
private:
223+
int n;
224+
vector<int> c;
231225
};
232226

233227
class MRUQueue {
234228
public:
235-
int n;
236-
vector<int> data;
237-
BinaryIndexedTree* tree;
238-
239229
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);
243232
tree = new BinaryIndexedTree(n + 2010);
244233
}
245234

246235
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+
}
254244
}
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;
258249
}
250+
251+
private:
252+
vector<int> q;
253+
BinaryIndexedTree* tree;
259254
};
260255

261256
/**
@@ -278,52 +273,49 @@ func newBinaryIndexedTree(n int) *BinaryIndexedTree {
278273
return &BinaryIndexedTree{n, c}
279274
}
280275
281-
func (this *BinaryIndexedTree) lowbit(x int) int {
282-
return x & -x
283-
}
284-
285276
func (this *BinaryIndexedTree) update(x, delta int) {
286277
for x <= this.n {
287278
this.c[x] += delta
288-
x += this.lowbit(x)
279+
x += x & -x
289280
}
290281
}
291282
292283
func (this *BinaryIndexedTree) query(x int) int {
293284
s := 0
294285
for x > 0 {
295286
s += this.c[x]
296-
x -= this.lowbit(x)
287+
x -= x & -x
297288
}
298289
return s
299290
}
300291
301292
type MRUQueue struct {
302-
data []int
293+
q []int
303294
tree *BinaryIndexedTree
304295
}
305296
306297
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
310301
}
311-
return MRUQueue{data, newBinaryIndexedTree(n + 2010)}
302+
return MRUQueue{q, newBinaryIndexedTree(n + 2010)}
312303
}
313304
314305
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
318309
if mid-this.tree.query(mid) >= k {
319-
right = mid
310+
r = mid
320311
} else {
321-
left = mid + 1
312+
l = mid + 1
322313
}
323314
}
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
327319
}
328320
329321
/**
@@ -333,6 +325,72 @@ func (this *MRUQueue) Fetch(k int) int {
333325
*/
334326
```
335327

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+
336394
### **...**
337395

338396
```

0 commit comments

Comments
 (0)