Skip to content

Commit 06d407d

Browse files
authored
Create design-most-recently-used-queue.cpp
1 parent 0e98516 commit 06d407d

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Time: ctor: O(n + m), m is the max number of calls
2+
// Space: fetch: O(log(n + m))
3+
4+
class MRUQueue {
5+
public:
6+
MRUQueue(int n)
7+
: bit_{n}
8+
, curr_{n} {
9+
for (int i = 0; i < n; ++i) {
10+
lookup_[i] = i + 1;
11+
}
12+
}
13+
14+
int fetch(int k) {
15+
int pos = bit_.binary_lift(k);
16+
int val = lookup_[pos];
17+
lookup_.erase(pos);
18+
bit_.add(pos, -1);
19+
bit_.add(curr_, 1);
20+
lookup_[curr_++] = val;
21+
return val;
22+
}
23+
24+
private:
25+
class BIT {
26+
public:
27+
static const int MAX_CALLS = 2000;
28+
29+
BIT(int n) : bit_(n + MAX_CALLS + 1) { // 0-indexed
30+
for (int i = 1; i < size(bit_); ++i) {
31+
bit_[i] = ((i - 1 < n) ? 1 : 0) + bit_[i - 1];
32+
}
33+
for (int i = size(bit_) - 1; i >= 1; --i) {
34+
int last_i = i - lower_bit(i);
35+
bit_[i] -= bit_[last_i];
36+
}
37+
}
38+
39+
void add(int i, int val) {
40+
++i;
41+
for (; i < size(bit_); i += lower_bit(i)) {
42+
bit_[i] += val;
43+
}
44+
}
45+
46+
int query(int i) const {
47+
++i;
48+
int total = 0;
49+
for (; i > 0; i -= lower_bit(i)) {
50+
total += bit_[i];
51+
}
52+
return total;
53+
}
54+
55+
int binary_lift(int k) const {
56+
int total = 0;
57+
int pos = 0;
58+
for (int i = floor_log2_x(size(bit_)); i >= 0; --i) {
59+
if (pos + (1 << i) < size(bit_) && !(total + bit_[pos + (1 << i)] >= k)) {
60+
total += bit_[pos + (1 << i)];
61+
pos += (1 << i);
62+
}
63+
}
64+
return (pos + 1) - 1;
65+
}
66+
67+
private:
68+
int lower_bit(int i) const {
69+
return i & -i;
70+
}
71+
72+
int floor_log2_x(int x) const {
73+
return 8 * sizeof(int) - __builtin_clz(x) - 1;
74+
};
75+
76+
vector<int> bit_;
77+
};
78+
79+
BIT bit_;
80+
unordered_map<int, int> lookup_;
81+
int curr_;
82+
};
83+
84+
// Time: ctor: O(n)
85+
// Space: fetch: O(sqrt(n))
86+
// sqrt decomposition solution
87+
class MRUQueue2 {
88+
public:
89+
MRUQueue2(int n)
90+
: buckets_(ceil(sqrt(n))) {
91+
for (int i = 0; i < n; ++i) {
92+
buckets_[i / size(buckets_)].emplace_back(i + 1);
93+
}
94+
}
95+
96+
int fetch(int k) {
97+
--k;
98+
int left = k / size(buckets_);
99+
int idx = k % size(buckets_);
100+
auto cit = begin(buckets_[left]);
101+
advance(cit, idx);
102+
int val = *cit;
103+
buckets_[left].erase(cit);
104+
buckets_.back().emplace_back(val);
105+
for (int i = size(buckets_) - 2; i >= left; --i) {
106+
int x = buckets_[i + 1].front();
107+
buckets_[i + 1].pop_front();
108+
buckets_[i].emplace_back(x);
109+
}
110+
return val;
111+
}
112+
113+
private:
114+
vector<list<int>> buckets_;
115+
};

0 commit comments

Comments
 (0)