@@ -126,32 +126,252 @@ tags:
126
126
127
127
<!-- solution:start -->
128
128
129
- ### 方法一
129
+ ### 方法一:排序 + 模拟
130
+
131
+ 我们将事件按照时间戳升序排序,如果时间戳相同,我们将 OFFLINE 事件排在 MESSAGE 事件之前。
132
+
133
+ 然后我们模拟事件的发生过程,使用 ` online_t ` 数组记录每个用户下一次上线的时间,用一个变量 ` lazy ` 记录所有用户还需要被提及的次数。
134
+
135
+ 遍历事件列表,根据事件类型进行处理:
136
+
137
+ - 如果是 ONLINE 事件,我们更新 ` online_t ` 数组;
138
+ - 如果是 ALL 事件,我们将 ` lazy ` 加一;
139
+ - 如果是 HERE 事件,我们遍历 ` online_t ` 数组,如果用户下一次上线的时间小于等于当前时间,我们将该用户的提及次数加一;
140
+ - 如果是 MESSAGE 事件,我们将提及的用户的提及次数加一。
141
+
142
+ 最后,如果 ` lazy ` 大于 0,我们将所有用户的提及次数加上 ` lazy ` 。
143
+
144
+ 时间复杂度 $O(n + m \times \log m \log M + L)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是用户总数和事件总数,而 $M$ 和 $L$ 分别是时间戳的最大值以及所有提及的字符串的总长度。
130
145
131
146
<!-- tabs:start -->
132
147
133
148
#### Python3
134
149
135
150
``` python
136
-
151
+ class Solution :
152
+ def countMentions (self , numberOfUsers : int , events : List[List[str ]]) -> List[int ]:
153
+ events.sort(key = lambda e : (int (e[1 ]), e[0 ][2 ]))
154
+ ans = [0 ] * numberOfUsers
155
+ online_t = [0 ] * numberOfUsers
156
+ lazy = 0
157
+ for etype, ts, s in events:
158
+ cur = int (ts)
159
+ if etype[0 ] == " O" :
160
+ online_t[int (s)] = cur + 60
161
+ elif s[0 ] == " A" :
162
+ lazy += 1
163
+ elif s[0 ] == " H" :
164
+ for i, t in enumerate (online_t):
165
+ if t <= cur:
166
+ ans[i] += 1
167
+ else :
168
+ for a in s.split():
169
+ ans[int (a[2 :])] += 1
170
+ if lazy:
171
+ for i in range (numberOfUsers):
172
+ ans[i] += lazy
173
+ return ans
137
174
```
138
175
139
176
#### Java
140
177
141
178
``` java
142
-
179
+ class Solution {
180
+ public int [] countMentions (int numberOfUsers , List<List<String > > events ) {
181
+ events. sort((a, b) - > {
182
+ int x = Integer . parseInt(a. get(1 ));
183
+ int y = Integer . parseInt(b. get(1 ));
184
+ if (x == y) {
185
+ return a. get(0 ). charAt(2 ) - b. get(0 ). charAt(2 );
186
+ }
187
+ return x - y;
188
+ });
189
+ int [] ans = new int [numberOfUsers];
190
+ int [] onlineT = new int [numberOfUsers];
191
+ int lazy = 0 ;
192
+ for (var e : events) {
193
+ String etype = e. get(0 );
194
+ int cur = Integer . parseInt(e. get(1 ));
195
+ String s = e. get(2 );
196
+ if (etype. charAt(0 ) == ' O' ) {
197
+ onlineT[Integer . parseInt(s)] = cur + 60 ;
198
+ } else if (s. charAt(0 ) == ' A' ) {
199
+ ++ lazy;
200
+ } else if (s. charAt(0 ) == ' H' ) {
201
+ for (int i = 0 ; i < numberOfUsers; ++ i) {
202
+ if (onlineT[i] <= cur) {
203
+ ++ ans[i];
204
+ }
205
+ }
206
+ } else {
207
+ for (var a : s. split(" " )) {
208
+ ++ ans[Integer . parseInt(a. substring(2 ))];
209
+ }
210
+ }
211
+ }
212
+ if (lazy > 0 ) {
213
+ for (int i = 0 ; i < numberOfUsers; ++ i) {
214
+ ans[i] += lazy;
215
+ }
216
+ }
217
+ return ans;
218
+ }
219
+ }
143
220
```
144
221
145
222
#### C++
146
223
147
224
``` cpp
148
-
225
+ class Solution {
226
+ public:
227
+ vector<int > countMentions(int numberOfUsers, vector<vector<string >>& events) {
228
+ ranges::sort(events, [ ] (const vector<string >& a, const vector<string >& b) {
229
+ int x = stoi(a[ 1] );
230
+ int y = stoi(b[ 1] );
231
+ if (x == y) {
232
+ return a[ 0] [ 2 ] < b[ 0] [ 2 ] ;
233
+ }
234
+ return x < y;
235
+ });
236
+
237
+ vector<int> ans(numberOfUsers, 0);
238
+ vector<int> onlineT(numberOfUsers, 0);
239
+ int lazy = 0;
240
+
241
+ for (const auto& e : events) {
242
+ string etype = e[0];
243
+ int cur = stoi(e[1]);
244
+ string s = e[2];
245
+
246
+ if (etype[0] == 'O') {
247
+ onlineT[stoi(s)] = cur + 60;
248
+ } else if (s[0] == 'A') {
249
+ lazy++;
250
+ } else if (s[0] == 'H') {
251
+ for (int i = 0; i < numberOfUsers; ++i) {
252
+ if (onlineT[i] <= cur) {
253
+ ++ans[i];
254
+ }
255
+ }
256
+ } else {
257
+ stringstream ss(s);
258
+ string token;
259
+ while (ss >> token) {
260
+ ans[stoi(token.substr(2))]++;
261
+ }
262
+ }
263
+ }
264
+
265
+ if (lazy > 0) {
266
+ for (int i = 0; i < numberOfUsers; ++i) {
267
+ ans[i] += lazy;
268
+ }
269
+ }
270
+
271
+ return ans;
272
+ }
273
+ };
149
274
```
150
275
151
276
#### Go
152
277
153
278
``` go
279
+ func countMentions (numberOfUsers int , events [][]string ) []int {
280
+ sort.Slice (events, func (i, j int ) bool {
281
+ x , _ := strconv.Atoi (events[i][1 ])
282
+ y , _ := strconv.Atoi (events[j][1 ])
283
+ if x == y {
284
+ return events[i][0 ][2 ] < events[j][0 ][2 ]
285
+ }
286
+ return x < y
287
+ })
288
+
289
+ ans := make ([]int , numberOfUsers)
290
+ onlineT := make ([]int , numberOfUsers)
291
+ lazy := 0
292
+
293
+ for _ , e := range events {
294
+ etype := e[0 ]
295
+ cur , _ := strconv.Atoi (e[1 ])
296
+ s := e[2 ]
297
+
298
+ if etype[0 ] == ' O' {
299
+ userID , _ := strconv.Atoi (s)
300
+ onlineT[userID] = cur + 60
301
+ } else if s[0 ] == ' A' {
302
+ lazy++
303
+ } else if s[0 ] == ' H' {
304
+ for i := 0 ; i < numberOfUsers; i++ {
305
+ if onlineT[i] <= cur {
306
+ ans[i]++
307
+ }
308
+ }
309
+ } else {
310
+ mentions := strings.Split (s, " " )
311
+ for _ , m := range mentions {
312
+ userID , _ := strconv.Atoi (m[2 :])
313
+ ans[userID]++
314
+ }
315
+ }
316
+ }
317
+
318
+ if lazy > 0 {
319
+ for i := 0 ; i < numberOfUsers; i++ {
320
+ ans[i] += lazy
321
+ }
322
+ }
323
+
324
+ return ans
325
+ }
326
+ ```
154
327
328
+ #### TypeScript
329
+
330
+ ``` ts
331
+ function countMentions(numberOfUsers : number , events : string [][]): number [] {
332
+ events .sort ((a , b ) => {
333
+ const x = + a [1 ];
334
+ const y = + b [1 ];
335
+ if (x === y ) {
336
+ return a [0 ].charAt (2 ) < b [0 ].charAt (2 ) ? - 1 : 1 ;
337
+ }
338
+ return x - y ;
339
+ });
340
+
341
+ const ans: number [] = Array (numberOfUsers ).fill (0 );
342
+ const onlineT: number [] = Array (numberOfUsers ).fill (0 );
343
+ let lazy = 0 ;
344
+
345
+ for (const [etype, ts, s] of events ) {
346
+ const cur = + ts ;
347
+ if (etype .charAt (0 ) === ' O' ) {
348
+ const userID = + s ;
349
+ onlineT [userID ] = cur + 60 ;
350
+ } else if (s .charAt (0 ) === ' A' ) {
351
+ lazy ++ ;
352
+ } else if (s .charAt (0 ) === ' H' ) {
353
+ for (let i = 0 ; i < numberOfUsers ; i ++ ) {
354
+ if (onlineT [i ] <= cur ) {
355
+ ans [i ]++ ;
356
+ }
357
+ }
358
+ } else {
359
+ const mentions = s .split (' ' );
360
+ for (const m of mentions ) {
361
+ const userID = + m .slice (2 );
362
+ ans [userID ]++ ;
363
+ }
364
+ }
365
+ }
366
+
367
+ if (lazy > 0 ) {
368
+ for (let i = 0 ; i < numberOfUsers ; i ++ ) {
369
+ ans [i ] += lazy ;
370
+ }
371
+ }
372
+
373
+ return ans ;
374
+ }
155
375
```
156
376
157
377
<!-- tabs:end -->
0 commit comments