Skip to content

feat: add solutions to lc problem: No.3433 #4005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 224 additions & 4 deletions solution/3400-3499/3433.Count Mentions Per User/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,32 +126,252 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一:排序 + 模拟

我们将事件按照时间戳升序排序,如果时间戳相同,我们将 OFFLINE 事件排在 MESSAGE 事件之前。

然后我们模拟事件的发生过程,使用 `online_t` 数组记录每个用户下一次上线的时间,用一个变量 `lazy` 记录所有用户还需要被提及的次数。

遍历事件列表,根据事件类型进行处理:

- 如果是 ONLINE 事件,我们更新 `online_t` 数组;
- 如果是 ALL 事件,我们将 `lazy` 加一;
- 如果是 HERE 事件,我们遍历 `online_t` 数组,如果用户下一次上线的时间小于等于当前时间,我们将该用户的提及次数加一;
- 如果是 MESSAGE 事件,我们将提及的用户的提及次数加一。

最后,如果 `lazy` 大于 0,我们将所有用户的提及次数加上 `lazy`。

时间复杂度 $O(n + m \times \log m \log M + L)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是用户总数和事件总数,而 $M$ 和 $L$ 分别是时间戳的最大值以及所有提及的字符串的总长度。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def countMentions(self, numberOfUsers: int, events: List[List[str]]) -> List[int]:
events.sort(key=lambda e: (int(e[1]), e[0][2]))
ans = [0] * numberOfUsers
online_t = [0] * numberOfUsers
lazy = 0
for etype, ts, s in events:
cur = int(ts)
if etype[0] == "O":
online_t[int(s)] = cur + 60
elif s[0] == "A":
lazy += 1
elif s[0] == "H":
for i, t in enumerate(online_t):
if t <= cur:
ans[i] += 1
else:
for a in s.split():
ans[int(a[2:])] += 1
if lazy:
for i in range(numberOfUsers):
ans[i] += lazy
return ans
```

#### Java

```java

class Solution {
public int[] countMentions(int numberOfUsers, List<List<String>> events) {
events.sort((a, b) -> {
int x = Integer.parseInt(a.get(1));
int y = Integer.parseInt(b.get(1));
if (x == y) {
return a.get(0).charAt(2) - b.get(0).charAt(2);
}
return x - y;
});
int[] ans = new int[numberOfUsers];
int[] onlineT = new int[numberOfUsers];
int lazy = 0;
for (var e : events) {
String etype = e.get(0);
int cur = Integer.parseInt(e.get(1));
String s = e.get(2);
if (etype.charAt(0) == 'O') {
onlineT[Integer.parseInt(s)] = cur + 60;
} else if (s.charAt(0) == 'A') {
++lazy;
} else if (s.charAt(0) == 'H') {
for (int i = 0; i < numberOfUsers; ++i) {
if (onlineT[i] <= cur) {
++ans[i];
}
}
} else {
for (var a : s.split(" ")) {
++ans[Integer.parseInt(a.substring(2))];
}
}
}
if (lazy > 0) {
for (int i = 0; i < numberOfUsers; ++i) {
ans[i] += lazy;
}
}
return ans;
}
}
```

#### C++

```cpp

class Solution {
public:
vector<int> countMentions(int numberOfUsers, vector<vector<string>>& events) {
ranges::sort(events, [](const vector<string>& a, const vector<string>& b) {
int x = stoi(a[1]);
int y = stoi(b[1]);
if (x == y) {
return a[0][2] < b[0][2];
}
return x < y;
});

vector<int> ans(numberOfUsers, 0);
vector<int> onlineT(numberOfUsers, 0);
int lazy = 0;

for (const auto& e : events) {
string etype = e[0];
int cur = stoi(e[1]);
string s = e[2];

if (etype[0] == 'O') {
onlineT[stoi(s)] = cur + 60;
} else if (s[0] == 'A') {
lazy++;
} else if (s[0] == 'H') {
for (int i = 0; i < numberOfUsers; ++i) {
if (onlineT[i] <= cur) {
++ans[i];
}
}
} else {
stringstream ss(s);
string token;
while (ss >> token) {
ans[stoi(token.substr(2))]++;
}
}
}

if (lazy > 0) {
for (int i = 0; i < numberOfUsers; ++i) {
ans[i] += lazy;
}
}

return ans;
}
};
```

#### Go

```go
func countMentions(numberOfUsers int, events [][]string) []int {
sort.Slice(events, func(i, j int) bool {
x, _ := strconv.Atoi(events[i][1])
y, _ := strconv.Atoi(events[j][1])
if x == y {
return events[i][0][2] < events[j][0][2]
}
return x < y
})

ans := make([]int, numberOfUsers)
onlineT := make([]int, numberOfUsers)
lazy := 0

for _, e := range events {
etype := e[0]
cur, _ := strconv.Atoi(e[1])
s := e[2]

if etype[0] == 'O' {
userID, _ := strconv.Atoi(s)
onlineT[userID] = cur + 60
} else if s[0] == 'A' {
lazy++
} else if s[0] == 'H' {
for i := 0; i < numberOfUsers; i++ {
if onlineT[i] <= cur {
ans[i]++
}
}
} else {
mentions := strings.Split(s, " ")
for _, m := range mentions {
userID, _ := strconv.Atoi(m[2:])
ans[userID]++
}
}
}

if lazy > 0 {
for i := 0; i < numberOfUsers; i++ {
ans[i] += lazy
}
}

return ans
}
```

#### TypeScript

```ts
function countMentions(numberOfUsers: number, events: string[][]): number[] {
events.sort((a, b) => {
const x = +a[1];
const y = +b[1];
if (x === y) {
return a[0].charAt(2) < b[0].charAt(2) ? -1 : 1;
}
return x - y;
});

const ans: number[] = Array(numberOfUsers).fill(0);
const onlineT: number[] = Array(numberOfUsers).fill(0);
let lazy = 0;

for (const [etype, ts, s] of events) {
const cur = +ts;
if (etype.charAt(0) === 'O') {
const userID = +s;
onlineT[userID] = cur + 60;
} else if (s.charAt(0) === 'A') {
lazy++;
} else if (s.charAt(0) === 'H') {
for (let i = 0; i < numberOfUsers; i++) {
if (onlineT[i] <= cur) {
ans[i]++;
}
}
} else {
const mentions = s.split(' ');
for (const m of mentions) {
const userID = +m.slice(2);
ans[userID]++;
}
}
}

if (lazy > 0) {
for (let i = 0; i < numberOfUsers; i++) {
ans[i] += lazy;
}
}

return ans;
}
```

<!-- tabs:end -->
Expand Down
Loading