@@ -126,32 +126,252 @@ tags:
126126
127127<!-- solution:start -->
128128
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$ 分别是时间戳的最大值以及所有提及的字符串的总长度。
130145
131146<!-- tabs:start -->
132147
133148#### Python3
134149
135150``` 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
137174```
138175
139176#### Java
140177
141178``` 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+ }
143220```
144221
145222#### C++
146223
147224``` 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+ };
149274```
150275
151276#### Go
152277
153278``` 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+ ```
154327
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+ }
155375```
156376
157377<!-- tabs:end -->
0 commit comments