Skip to content

Commit 133f7e1

Browse files
authored
feat: add solutions to lc problems: No.2102,2125 (#2776)
* No.2102.Sequentially Ordinal Rank Tracker * No.2125.Number of Laser Beams in a Bank
1 parent 938b0f4 commit 133f7e1

File tree

16 files changed

+663
-200
lines changed

16 files changed

+663
-200
lines changed

solution/2100-2199/2102.Sequentially Ordinal Rank Tracker/README.md

+183
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,187 @@ tracker.get(); // 从好到坏的景点为:branford, orlando, alp
8181

8282
## 解法
8383

84+
### 方法一:有序集合
85+
86+
我们可以使用有序集合来存储景点,用一个变量 $i$ 来记录当前查询的次数,初始时 $i = -1$。
87+
88+
调用 `add` 方法时,我们将景点的评分取负数,这样就可以使用有序集合按照评分从大到小排序,如果评分相同,按照景点名字的字典序从小到大排序。
89+
90+
调用 `get` 方法时,我们将 $i$ 加一,然后返回有序集合中第 $i$ 个景点的名字。
91+
92+
每次操作的时间复杂度为 $O(\log n)$,其中 $n$ 为已添加的景点数。空间复杂度为 $O(n)$。
93+
94+
<!-- tabs:start -->
95+
96+
```python
97+
from sortedcontainers import SortedList
98+
99+
100+
class SORTracker:
101+
102+
def __init__(self):
103+
self.sl = SortedList()
104+
self.i = -1
105+
106+
def add(self, name: str, score: int) -> None:
107+
self.sl.add((-score, name))
108+
109+
def get(self) -> str:
110+
self.i += 1
111+
return self.sl[self.i][1]
112+
113+
114+
# Your SORTracker object will be instantiated and called as such:
115+
# obj = SORTracker()
116+
# obj.add(name,score)
117+
# param_2 = obj.get()
118+
```
119+
120+
```cpp
121+
#include <ext/pb_ds/assoc_container.hpp>
122+
#include <ext/pb_ds/hash_policy.hpp>
123+
using namespace __gnu_pbds;
124+
125+
template <class T>
126+
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
127+
128+
class SORTracker {
129+
public:
130+
SORTracker() {
131+
}
132+
133+
void add(string name, int score) {
134+
st.insert({-score, name});
135+
}
136+
137+
string get() {
138+
return st.find_by_order(++i)->second;
139+
}
140+
141+
private:
142+
ordered_set<pair<int, string>> st;
143+
int i = -1;
144+
};
145+
146+
/**
147+
* Your SORTracker object will be instantiated and called as such:
148+
* SORTracker* obj = new SORTracker();
149+
* obj->add(name,score);
150+
* string param_2 = obj->get();
151+
*/
152+
```
153+
154+
<!-- tabs:end -->
155+
156+
### 方法二:双优先队列(大小根堆)
157+
158+
我们注意到,由于本题中的查询操作是按照严格递增的顺序进行的,因此我们可以使用类似于数据流中的中位数的方法,定义两个优先队列 `good``bad`,其中 `good` 是一个小根堆,存储当前最好的景点,`bad` 是一个大根堆,存储当前第 $i$ 好的景点。
159+
160+
每次调用 `add` 方法时,我们将景点的评分和名字加入 `good` 中,然后将 `good` 中的最差的景点加入 `bad` 中。
161+
162+
每次调用 `get` 方法时,我们将 `bad` 中的最好的景点加入 `good` 中,然后返回 `good` 中的最差的景点。
163+
164+
每次操作的时间复杂度为 $O(\log n)$,其中 $n$ 为已添加的景点数。空间复杂度为 $O(n)$。
165+
166+
<!-- tabs:start -->
167+
168+
```python
169+
class Node:
170+
def __init__(self, s: str):
171+
self.s = s
172+
173+
def __lt__(self, other):
174+
return self.s > other.s
175+
176+
177+
class SORTracker:
178+
179+
def __init__(self):
180+
self.good = []
181+
self.bad = []
182+
183+
def add(self, name: str, score: int) -> None:
184+
score, node = heappushpop(self.good, (score, Node(name)))
185+
heappush(self.bad, (-score, node.s))
186+
187+
def get(self) -> str:
188+
score, name = heappop(self.bad)
189+
heappush(self.good, (-score, Node(name)))
190+
return self.good[0][1].s
191+
192+
193+
# Your SORTracker object will be instantiated and called as such:
194+
# obj = SORTracker()
195+
# obj.add(name,score)
196+
# param_2 = obj.get()
197+
```
198+
199+
```java
200+
class SORTracker {
201+
private PriorityQueue<Map.Entry<Integer, String>> good = new PriorityQueue<>(
202+
(a, b)
203+
-> a.getKey().equals(b.getKey()) ? b.getValue().compareTo(a.getValue())
204+
: a.getKey() - b.getKey());
205+
private PriorityQueue<Map.Entry<Integer, String>> bad = new PriorityQueue<>(
206+
(a, b)
207+
-> a.getKey().equals(b.getKey()) ? a.getValue().compareTo(b.getValue())
208+
: b.getKey() - a.getKey());
209+
210+
public SORTracker() {
211+
}
212+
213+
public void add(String name, int score) {
214+
good.offer(Map.entry(score, name));
215+
bad.offer(good.poll());
216+
}
217+
218+
public String get() {
219+
good.offer(bad.poll());
220+
return good.peek().getValue();
221+
}
222+
}
223+
224+
/**
225+
* Your SORTracker object will be instantiated and called as such:
226+
* SORTracker obj = new SORTracker();
227+
* obj.add(name,score);
228+
* String param_2 = obj.get();
229+
*/
230+
```
231+
232+
```cpp
233+
using pis = pair<int, string>;
234+
235+
class SORTracker {
236+
public:
237+
SORTracker() {
238+
}
239+
240+
void add(string name, int score) {
241+
good.push({-score, name});
242+
bad.push(good.top());
243+
good.pop();
244+
}
245+
246+
string get() {
247+
good.push(bad.top());
248+
bad.pop();
249+
return good.top().second;
250+
}
251+
252+
private:
253+
priority_queue<pis, vector<pis>, less<pis>> good;
254+
priority_queue<pis, vector<pis>, greater<pis>> bad;
255+
};
256+
257+
/**
258+
* Your SORTracker object will be instantiated and called as such:
259+
* SORTracker* obj = new SORTracker();
260+
* obj->add(name,score);
261+
* string param_2 = obj->get();
262+
*/
263+
```
264+
265+
<!-- tabs:end -->
266+
84267
<!-- end -->

solution/2100-2199/2102.Sequentially Ordinal Rank Tracker/README_EN.md

+183
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,187 @@ tracker.get(); // Sorted locations: branford, orlando, alpine, alps
7777

7878
## Solutions
7979

80+
### Solution 1: Ordered Set
81+
82+
We can use an ordered set to store the attractions, and a variable $i$ to record the current number of queries, initially $i = -1$.
83+
84+
When calling the `add` method, we take the negative of the attraction's rating, so that we can use the ordered set to sort by rating in descending order. If the ratings are the same, sort by the dictionary order of the attraction names in ascending order.
85+
86+
When calling the `get` method, we increment $i$ by one, and then return the name of the $i$-th attraction in the ordered set.
87+
88+
The time complexity of each operation is $O(\log n)$, where $n$ is the number of added attractions. The space complexity is $O(n)$.
89+
90+
<!-- tabs:start -->
91+
92+
```python
93+
from sortedcontainers import SortedList
94+
95+
96+
class SORTracker:
97+
98+
def __init__(self):
99+
self.sl = SortedList()
100+
self.i = -1
101+
102+
def add(self, name: str, score: int) -> None:
103+
self.sl.add((-score, name))
104+
105+
def get(self) -> str:
106+
self.i += 1
107+
return self.sl[self.i][1]
108+
109+
110+
# Your SORTracker object will be instantiated and called as such:
111+
# obj = SORTracker()
112+
# obj.add(name,score)
113+
# param_2 = obj.get()
114+
```
115+
116+
```cpp
117+
#include <ext/pb_ds/assoc_container.hpp>
118+
#include <ext/pb_ds/hash_policy.hpp>
119+
using namespace __gnu_pbds;
120+
121+
template <class T>
122+
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
123+
124+
class SORTracker {
125+
public:
126+
SORTracker() {
127+
}
128+
129+
void add(string name, int score) {
130+
st.insert({-score, name});
131+
}
132+
133+
string get() {
134+
return st.find_by_order(++i)->second;
135+
}
136+
137+
private:
138+
ordered_set<pair<int, string>> st;
139+
int i = -1;
140+
};
141+
142+
/**
143+
* Your SORTracker object will be instantiated and called as such:
144+
* SORTracker* obj = new SORTracker();
145+
* obj->add(name,score);
146+
* string param_2 = obj->get();
147+
*/
148+
```
149+
150+
<!-- tabs:end -->
151+
152+
### Solution 2: Double Priority Queue (Min-Max Heap)
153+
154+
We notice that the query operations in this problem are performed in strictly increasing order. Therefore, we can use a method similar to the median in the data stream. We define two priority queues `good` and `bad`. `good` is a min-heap, storing the current best attractions, and `bad` is a max-heap, storing the current $i$-th best attraction.
155+
156+
Each time the `add` method is called, we add the attraction's rating and name to `good`, and then add the worst attraction in `good` to `bad`.
157+
158+
Each time the `get` method is called, we add the best attraction in `bad` to `good`, and then return the worst attraction in `good`.
159+
160+
The time complexity of each operation is $O(\log n)$, where $n$ is the number of added attractions. The space complexity is $O(n)$.
161+
162+
<!-- tabs:start -->
163+
164+
```python
165+
class Node:
166+
def __init__(self, s: str):
167+
self.s = s
168+
169+
def __lt__(self, other):
170+
return self.s > other.s
171+
172+
173+
class SORTracker:
174+
175+
def __init__(self):
176+
self.good = []
177+
self.bad = []
178+
179+
def add(self, name: str, score: int) -> None:
180+
score, node = heappushpop(self.good, (score, Node(name)))
181+
heappush(self.bad, (-score, node.s))
182+
183+
def get(self) -> str:
184+
score, name = heappop(self.bad)
185+
heappush(self.good, (-score, Node(name)))
186+
return self.good[0][1].s
187+
188+
189+
# Your SORTracker object will be instantiated and called as such:
190+
# obj = SORTracker()
191+
# obj.add(name,score)
192+
# param_2 = obj.get()
193+
```
194+
195+
```java
196+
class SORTracker {
197+
private PriorityQueue<Map.Entry<Integer, String>> good = new PriorityQueue<>(
198+
(a, b)
199+
-> a.getKey().equals(b.getKey()) ? b.getValue().compareTo(a.getValue())
200+
: a.getKey() - b.getKey());
201+
private PriorityQueue<Map.Entry<Integer, String>> bad = new PriorityQueue<>(
202+
(a, b)
203+
-> a.getKey().equals(b.getKey()) ? a.getValue().compareTo(b.getValue())
204+
: b.getKey() - a.getKey());
205+
206+
public SORTracker() {
207+
}
208+
209+
public void add(String name, int score) {
210+
good.offer(Map.entry(score, name));
211+
bad.offer(good.poll());
212+
}
213+
214+
public String get() {
215+
good.offer(bad.poll());
216+
return good.peek().getValue();
217+
}
218+
}
219+
220+
/**
221+
* Your SORTracker object will be instantiated and called as such:
222+
* SORTracker obj = new SORTracker();
223+
* obj.add(name,score);
224+
* String param_2 = obj.get();
225+
*/
226+
```
227+
228+
```cpp
229+
using pis = pair<int, string>;
230+
231+
class SORTracker {
232+
public:
233+
SORTracker() {
234+
}
235+
236+
void add(string name, int score) {
237+
good.push({-score, name});
238+
bad.push(good.top());
239+
good.pop();
240+
}
241+
242+
string get() {
243+
good.push(bad.top());
244+
bad.pop();
245+
return good.top().second;
246+
}
247+
248+
private:
249+
priority_queue<pis, vector<pis>, less<pis>> good;
250+
priority_queue<pis, vector<pis>, greater<pis>> bad;
251+
};
252+
253+
/**
254+
* Your SORTracker object will be instantiated and called as such:
255+
* SORTracker* obj = new SORTracker();
256+
* obj->add(name,score);
257+
* string param_2 = obj->get();
258+
*/
259+
```
260+
261+
<!-- tabs:end -->
262+
80263
<!-- end -->

0 commit comments

Comments
 (0)