|
| 1 | +# [Problem 3433: Count Mentions Per User](https://leetcode.com/problems/count-mentions-per-user/description/?envType=daily-question) |
| 2 | + |
| 3 | +## Initial thoughts (stream-of-consciousness) |
| 4 | +We need to simulate users going offline for 60 time units and messages that mention users. Each message can be "ALL" (mention every user regardless of online state), "HERE" (mention only currently online users), or a sequence of "id<number>" tokens (which can include duplicates and mention offline users too). Important detail: status changes (OFFLINE) at a timestamp are processed before any MESSAGE at the same timestamp. That implies we should process events in timestamp order and ensure OFFLINE events at the same timestamp are handled before MESSAGE events. A straightforward approach is to track, for each user, until what time they remain offline (offline_until). When offline_until > t the user is offline at time t; otherwise they are online. |
| 5 | + |
| 6 | +Since constraints are small (<=100 users, <=100 events), a simple simulation with sorting events by (timestamp, type-priority) will be efficient and easy to implement. |
| 7 | + |
| 8 | +## Refining the problem, round 2 thoughts |
| 9 | +- We should sort events by timestamp and ensure OFFLINE events come before MESSAGE events at the same timestamp (tie-breaker). |
| 10 | +- For OFFLINE events: set offline_until[user] = timestamp + 60. |
| 11 | +- For MESSAGE events: |
| 12 | + - If token == "ALL": increment every user's mention count. |
| 13 | + - If token == "HERE": increment every user with offline_until <= timestamp (i.e., online). |
| 14 | + - Else: split the string by spaces and for each "idX" increment that user's count (duplicates counted). |
| 15 | +- Edge cases: |
| 16 | + - Input might already be sorted, but we explicitly sort to enforce the tie-breaker rule. |
| 17 | + - OFFLINE events are guaranteed to reference an online user at that moment (so no double-offline). |
| 18 | +- Complexity: Sorting O(E log E) where E <= 100 negligible. Processing each event is at worst O(U) per event (for ALL/HERE) or O(k) for explicit ids, so overall O(E * max(U, k)). Space O(U). |
| 19 | + |
| 20 | +## Attempted solution(s) |
| 21 | +```python |
| 22 | +from typing import List |
| 23 | + |
| 24 | +class Solution: |
| 25 | + def countMentions(self, numberOfUsers: int, events: List[List[str]]) -> List[int]: |
| 26 | + # Parse events to (timestamp:int, type:str, payload:str) |
| 27 | + parsed = [] |
| 28 | + for ev in events: |
| 29 | + typ, ts_str, payload = ev |
| 30 | + ts = int(ts_str) |
| 31 | + parsed.append((ts, typ, payload)) |
| 32 | + # Sort by timestamp, with OFFLINE before MESSAGE at same timestamp |
| 33 | + # OFFLINE priority = 0, MESSAGE priority = 1 |
| 34 | + parsed.sort(key=lambda x: (x[0], 0 if x[1] == "OFFLINE" else 1)) |
| 35 | + |
| 36 | + mentions = [0] * numberOfUsers |
| 37 | + # offline_until[i] stores the time when user i becomes online again. |
| 38 | + # user is offline at time t iff offline_until[i] > t |
| 39 | + offline_until = [0] * numberOfUsers # initially 0 => online for all t >= 0 |
| 40 | + |
| 41 | + for ts, typ, payload in parsed: |
| 42 | + if typ == "OFFLINE": |
| 43 | + user_id = int(payload) |
| 44 | + # user goes offline at ts for 60 units -> back online at ts + 60 |
| 45 | + offline_until[user_id] = ts + 60 |
| 46 | + else: # MESSAGE |
| 47 | + if payload == "ALL": |
| 48 | + # mention all users regardless of online status |
| 49 | + for i in range(numberOfUsers): |
| 50 | + mentions[i] += 1 |
| 51 | + elif payload == "HERE": |
| 52 | + # mention only online users at this timestamp |
| 53 | + for i in range(numberOfUsers): |
| 54 | + if offline_until[i] <= ts: |
| 55 | + mentions[i] += 1 |
| 56 | + else: |
| 57 | + # list of id<number> tokens, separated by single spaces |
| 58 | + tokens = payload.split() |
| 59 | + for tok in tokens: |
| 60 | + # tok format is "id<number>" |
| 61 | + if tok.startswith("id"): |
| 62 | + uid = int(tok[2:]) |
| 63 | + mentions[uid] += 1 |
| 64 | + else: |
| 65 | + # defensive: shouldn't happen per problem statement |
| 66 | + pass |
| 67 | + return mentions |
| 68 | +``` |
| 69 | +- Notes: |
| 70 | + - We sort events by (timestamp, OFFLINE-before-MESSAGE) to respect the rule that status changes at a timestamp are applied before messages at the same timestamp. |
| 71 | + - offline_until[user] > t means offline; using offline_until[user] <= t to check online. |
| 72 | + - Complexity: O(E log E) for sorting plus O(E * U) in worst case for processing (when using ALL/HERE), where E <= 100 and U <= 100. Space O(U) for offline tracking and result array. |
0 commit comments