@@ -74,33 +74,27 @@ counter.getHits(301); // 在时刻 301 统计过去 5 分钟内的敲击次数
74
74
75
75
<!-- solution:start -->
76
76
77
- ### 方法一
77
+ ### 方法一:二分查找
78
+
79
+ 由于 ` timestamp ` 是单调递增的,我们可以使用一个数组 ` ts ` 来存储所有的 ` timestamp ` ,然后在 ` getHits ` 方法中使用二分查找找到第一个大于等于 ` timestamp - 300 + 1 ` 的位置,然后返回 ` ts ` 的长度减去这个位置即可。
80
+
81
+ 时间复杂度方面,` hit ` 方法的时间复杂度为 $O(1)$,` getHits ` 方法的时间复杂度为 $O(\log n)$。其中 $n$ 为 ` ts ` 的长度。
78
82
79
83
<!-- tabs:start -->
80
84
81
85
#### Python3
82
86
83
87
``` python
84
88
class HitCounter :
89
+
85
90
def __init__ (self ):
86
- """
87
- Initialize your data structure here.
88
- """
89
- self .counter = Counter()
91
+ self .ts = []
90
92
91
93
def hit (self , timestamp : int ) -> None :
92
- """
93
- Record a hit.
94
- @param timestamp - The current timestamp (in seconds granularity).
95
- """
96
- self .counter[timestamp] += 1
94
+ self .ts.append(timestamp)
97
95
98
96
def getHits (self , timestamp : int ) -> int :
99
- """
100
- Return the number of hits in the past 5 minutes.
101
- @param timestamp - The current timestamp (in seconds granularity).
102
- """
103
- return sum ([v for t, v in self .counter.items() if t + 300 > timestamp])
97
+ return len (self .ts) - bisect_left(self .ts, timestamp - 300 + 1 )
104
98
105
99
106
100
# Your HitCounter object will be instantiated and called as such:
@@ -113,34 +107,31 @@ class HitCounter:
113
107
114
108
``` java
115
109
class HitCounter {
110
+ private List<Integer > ts = new ArrayList<> ();
116
111
117
- private Map<Integer , Integer > counter;
118
-
119
- /* * Initialize your data structure here. */
120
112
public HitCounter () {
121
- counter = new HashMap<> ();
122
113
}
123
114
124
- /**
125
- Record a hit.
126
- @param timestamp - The current timestamp (in seconds granularity).
127
- */
128
115
public void hit (int timestamp ) {
129
- counter . put (timestamp, counter . getOrDefault(timestamp, 0 ) + 1 );
116
+ ts . add (timestamp);
130
117
}
131
118
132
- /**
133
- Return the number of hits in the past 5 minutes.
134
- @param timestamp - The current timestamp (in seconds granularity).
135
- */
136
119
public int getHits (int timestamp ) {
137
- int hits = 0 ;
138
- for (Map . Entry<Integer , Integer > entry : counter. entrySet()) {
139
- if (entry. getKey() + 300 > timestamp) {
140
- hits += entry. getValue();
120
+ int l = search(timestamp - 300 + 1 );
121
+ return ts. size() - l;
122
+ }
123
+
124
+ private int search (int x ) {
125
+ int l = 0 , r = ts. size();
126
+ while (l < r) {
127
+ int mid = (l + r) >> 1 ;
128
+ if (ts. get(mid) >= x) {
129
+ r = mid;
130
+ } else {
131
+ l = mid + 1 ;
141
132
}
142
133
}
143
- return hits ;
134
+ return l ;
144
135
}
145
136
}
146
137
@@ -152,39 +143,142 @@ class HitCounter {
152
143
*/
153
144
```
154
145
146
+ #### C++
147
+
148
+ ``` cpp
149
+ class HitCounter {
150
+ public:
151
+ HitCounter() {
152
+
153
+ }
154
+
155
+ void hit (int timestamp) {
156
+ ts.push_back(timestamp);
157
+ }
158
+
159
+ int getHits(int timestamp) {
160
+ return ts.end() - lower_bound(ts.begin(), ts.end(), timestamp - 300 + 1);
161
+ }
162
+
163
+ private:
164
+ vector<int > ts;
165
+ };
166
+
167
+ /**
168
+ * Your HitCounter object will be instantiated and called as such:
169
+ * HitCounter* obj = new HitCounter();
170
+ * obj->hit(timestamp);
171
+ * int param_2 = obj->getHits(timestamp);
172
+ * /
173
+ ```
174
+
175
+ #### Go
176
+
177
+ ```go
178
+ type HitCounter struct {
179
+ ts []int
180
+ }
181
+
182
+ func Constructor() HitCounter {
183
+ return HitCounter{}
184
+ }
185
+
186
+ func (this *HitCounter) Hit(timestamp int) {
187
+ this.ts = append(this.ts, timestamp)
188
+ }
189
+
190
+ func (this *HitCounter) GetHits(timestamp int) int {
191
+ return len(this.ts) - sort.SearchInts(this.ts, timestamp-300+1)
192
+ }
193
+
194
+ /**
195
+ * Your HitCounter object will be instantiated and called as such:
196
+ * obj := Constructor();
197
+ * obj.Hit(timestamp);
198
+ * param_2 := obj.GetHits(timestamp);
199
+ */
200
+ ```
201
+
202
+ #### TypeScript
203
+
204
+ ``` ts
205
+ class HitCounter {
206
+ private ts: number [] = [];
207
+
208
+ constructor () {}
209
+
210
+ hit(timestamp : number ): void {
211
+ this .ts .push (timestamp );
212
+ }
213
+
214
+ getHits(timestamp : number ): number {
215
+ const search = (x : number ) => {
216
+ let [l, r] = [0 , this .ts .length ];
217
+ while (l < r ) {
218
+ const mid = (l + r ) >> 1 ;
219
+ if (this .ts [mid ] >= x ) {
220
+ r = mid ;
221
+ } else {
222
+ l = mid + 1 ;
223
+ }
224
+ }
225
+ return l ;
226
+ };
227
+ return this .ts .length - search (timestamp - 300 + 1 );
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Your HitCounter object will be instantiated and called as such:
233
+ * var obj = new HitCounter()
234
+ * obj.hit(timestamp)
235
+ * var param_2 = obj.getHits(timestamp)
236
+ */
237
+ ```
238
+
155
239
#### Rust
156
240
157
241
``` rust
158
- use std :: { collections :: BinaryHeap , cmp :: Reverse };
159
-
160
242
struct HitCounter {
161
- /// A min heap
162
- pq : BinaryHeap <Reverse <i32 >>,
243
+ ts : Vec <i32 >,
163
244
}
164
245
246
+ /**
247
+ * `&self` means the method takes an immutable reference.
248
+ * If you need a mutable reference, change it to `&mut self` instead.
249
+ */
165
250
impl HitCounter {
166
251
fn new () -> Self {
167
- Self {
168
- pq : BinaryHeap :: new (),
169
- }
252
+ HitCounter { ts : Vec :: new () }
170
253
}
171
254
172
255
fn hit (& mut self , timestamp : i32 ) {
173
- self . pq . push (Reverse ( timestamp ) );
256
+ self . ts . push (timestamp );
174
257
}
175
258
176
- fn get_hits (& mut self , timestamp : i32 ) -> i32 {
177
- while let Some (Reverse (min_elem )) = self . pq. peek () {
178
- if * min_elem <= timestamp - 300 {
179
- self . pq. pop ();
259
+ fn get_hits (& self , timestamp : i32 ) -> i32 {
260
+ let l = self . search (timestamp - 300 + 1 );
261
+ (self . ts. len () - l ) as i32
262
+ }
263
+
264
+ fn search (& self , x : i32 ) -> usize {
265
+ let (mut l , mut r ) = (0 , self . ts. len ());
266
+ while l < r {
267
+ let mid = (l + r ) / 2 ;
268
+ if self . ts[mid ] >= x {
269
+ r = mid ;
180
270
} else {
181
- break ;
271
+ l = mid + 1 ;
182
272
}
183
273
}
184
-
185
- self . pq. len () as i32
274
+ l
186
275
}
187
- }
276
+ }/**
277
+ * Your HitCounter object will be instantiated and called as such:
278
+ * let obj = HitCounter::new();
279
+ * obj.hit(timestamp);
280
+ * let ret_2: i32 = obj.get_hits(timestamp);
281
+ */
188
282
```
189
283
190
284
<!-- tabs:end -->
0 commit comments