[LeetCode] Count Mentions Per User

3433. Count Mentions Per User

You are given an integer numberOfUsers representing the total number of users and an array events of size n x 3.

Each events[i] can be either of the following two types:

  1. Message Event: ["MESSAGE", "timestampi", "mentions_stringi"]

    • This event indicates that a set of users was mentioned in a message at timestampi.

    • The mentions_stringi string can contain one of the following tokens:

      • id<number>: where <number> is an integer in range [0,numberOfUsers - 1]. There can be multiple ids separated by a single whitespace and may contain duplicates. This can mention even the offline users.
      • ALL: mentions all users.
      • HERE: mentions all online users.
  2. Offline Event: ["OFFLINE", "timestampi", "idi"]

    • This event indicates that the user idi had become offline at timestampi for 60 time units. The user will automatically be online again at time timestampi + 60.

Return an array mentions where mentions[i] represents the number of mentions the user with id i has across all MESSAGE events.

All users are initially online, and if a user goes offline or comes back online, their status change is processed before handling any message event that occurs at the same timestamp.

Note that a user can be mentioned multiple times in a single message event, and each mention should be counted separately.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package main

import (
"sort"
"strconv"
"strings"
)

func countMentions(numberOfUsers int, events [][]string) []int {
res := make([]int, numberOfUsers)
us := make(map[int]struct{})
for i := 0; i < numberOfUsers; i++ {
us[i] = struct{}{}
}

var q []struct {
time, id int
}

sort.Slice(events, func(i, j int) bool {
t1, _ := strconv.ParseInt(events[i][1], 10, 64)
t2, _ := strconv.ParseInt(events[j][1], 10, 64)
if t1 == t2 {
return events[i][0] > events[j][0]
}
return t1 < t2
})

for _, e := range events {
time, _ := strconv.ParseInt(e[1], 10, 64)

for len(q) > 0 && q[0].time <= int(time) {
id := q[0].id
q = q[1:]
us[id] = struct{}{}
}

if e[0] == "MESSAGE" {
if e[2] == "ALL" {
for i := 0; i < numberOfUsers; i++ {
res[i]++
}
} else if e[2] == "HERE" {
for id := range us {
res[id]++
}
} else {
ids := getIds(e[2])
for _, id := range ids {
res[id]++
}
}
} else {
id, _ := strconv.Atoi(e[2])
delete(us, id)
q = append(q, struct {
time, id int
}{
time: int(time) + 60,
id: id,
})
}
}

return res
}

func getIds(s string) []int {
var res []int
val := 0
s += " "
for i := 0; i < len(s); i++ {
if s[i] == ' ' {
res = append(res, val)
val = 0
} else if '0' <= s[i] && s[i] <= '9' {
val = val*10 + int(s[i]-'0')
}
}
return res
}

Author: Song Hayoung
Link: https://songhayoung.github.io/2025/01/26/PS/LeetCode/count-mentions-per-user/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.