Beats 100% || Easy PYTHON SOLUTION using CUSTOM SORT
IntuitionProblem Context:You have numberOfUsers users, and each user can either be online or offline.Users can send messages (either to specific users, to all u
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
**Problem Context:**

You have numberOfUsers users, and each user can either be online or offline.

Users can send messages (either to specific users, to all users, or to users who are currently online).

The goal is to count how many times each user is mentioned in the messages.
Key Ideas:

1.Tracking User Status (Online/Offline):
The user_online list tracks whether a user is online or offline at any given point.

2.If a user goes offline (OFFLINE event), they are marked as offline in the user_online list, and their "back online time" (i.e., the time they’ll be back online) is stored in back_online.

3.The user will automatically be marked online after a certain period (1 minute) after they go offline.

****4.Handling Messages:****
There are three types of messages:
*"ALL":* All users are mentioned, so we increment the count for every user.
*"HERE":* Only users who are currently online are mentioned, so we increment the count for online users.
Specific User(s): In this case, you parse the user IDs and increment the count for each of those users.

***5.Event Sorting:***
The events are sorted first by the timestamp. This ensures events are processed in chronological order.

Additionally, OFFLINE events come before other events with the same timestamp, so the system first handles the user going offline before processing any messages sent at that timestamp.

```
sorted_events = sorted(events, key=lambda x: (int(x[1]), x[0] != "OFFLINE"))
```
***Let’s break it down:***

**sorted(events, ...):**

1. The sorted() function is sorting the events list.
events is a list of events, where each event is a list of the form [event_type, timestamp, data].

2. key=lambda x: (int(x[1]), x[0] != "OFFLINE"):
key is a function that extracts the sorting criteria. In this case, it's a lambda function.

3. The lambda function is applied to each event x in the events list.
4. The lambda function returns a tuple (int(x[1]), x[0] != "OFFLINE") for each event, and this tuple is used to sort the events.

**Breakdown of the Tuple:**

***int(x[1]):***  x[1] refers to the timestamp in the event (the second element of the event list).
The timestamp is being converted to an integer using int(x[1]) to ensure that it is properly compared as an integer during sorting. This is important for numerical sorting (instead of lexicographical sorting which could happen if it was treated as a string).

```
x[0] != "OFFLINE":
```
x[0] refers to the event type (the first element of the event list), which could be "OFFLINE", "MESSAGE", etc.

x[0] != "OFFLINE" evaluates to True or False. In Python, True is treated as 1 and False is treated as 0 when sorting.

The purpose of this part is to prioritize OFFLINE events over others when events have the same timestamp. The expression x[0] != "OFFLINE" ensures that OFFLINE events will have a lower sorting value (since False or 0 comes before True or 1), meaning they come first if two events have the same timesta

# Approach
<!-- Describe your approach to solving the problem. -->
**Initial Setup:**

**You start by initializing:**

ans: A list to keep track of how many times each user has been mentioned.
user_online: A list of booleans indicating if a user is online (True) or offline (False).
back_online: A dictionary that keeps track of when each user will be back online (if they are offline).

**Processing Events:**
You process each event in sorted order:
If it’s an OFFLINE event, you mark the user as offline and set the time they’ll come back online (current time + 60 seconds).

If it’s a MESSAGE event, you:
Update the online status of users who should be back online by comparing the event timestamp with their "back online time."
Then, based on the message type (ALL, HERE, or specific users), you update the mention count (ans list) accordingly.

Counting Mentions:
For a MESSAGE event:
If the message is to ALL, all users get mentioned.
If it’s to HERE, only users who are online get mentioned.
If it’s to specific users, you increment the count for those specific users.

# Example Walkthrough:
```
[
    ['OFFLINE', '10', 'user2'],
    ['MESSAGE', '20', 'ALL'],
    ['MESSAGE', '30', 'HERE'],
    ['MESSAGE', '40', 'user1 user2']
]

```
**Processing the OFFLINE event at time 10:**
User 2 goes offline at timestamp 10, and back_online[user2] is set to 70 (10 + 60 seconds).

**Processing the MESSAGE event at time 20:**
The message is to ALL, so every user gets mentioned. ans is updated for all users.

**Processing the MESSAGE event at time 30:**
The message is to HERE, so only users who are online get mentioned. If user 2 is still offline (since 30 < 70), they are not mentioned. ans is updated for users who are online.

**Processing the MESSAGE event at time 40:**
The message mentions specific users (user1 and user2). Even though user 2 is offline, their count is still incremented because they were included in the message.
The solution handles the "online/offline" status of users dynamically and ensures mentions are only counted when a user is online at the time the message is sent.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
Sorting the events is the most expensive operation, with a time complexity of $$O(E * log E)$$, where E is the number of events.

Processing each event takes $$O(1)$$ or $$O(n)$$ depending on the number of users being mentioned in a message, so the overall complexity is dominated by the sorting step.


- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
The total space complexity is the sum of the space required for each variable:

ans: $$O(n)$$
user_online: $$O(n)$$
back_online: $$O(n)$$
sorted_events: $$O(E)$$

# Code
```python3 []
class Solution:
    def countMentions(self, numberOfUsers: int, events: List[List[str]]) -> List[int]:
        ans = [0] * numberOfUsers
        user_online = [True] * numberOfUsers
        back_online = {}

        sorted_events = sorted(events, key=lambda x: (int(x[1]), x[0] != "OFFLINE"))
        for event in sorted_events:  
            event_type, timestamp, data = event
            timestamp = int(timestamp)
            
            if event_type == 'OFFLINE':
                user_id = int(data)
                user_online[user_id] = False
                back_online[user_id] = timestamp + 60  
            
            elif event_type == 'MESSAGE':
                for user_id, back_time in list(back_online.items()):
                    if timestamp >= back_time:
                        user_online[user_id] = True
                        del back_online[user_id]
                
                if data == 'ALL':
                    for i in range(numberOfUsers):
                        ans[i] += 1
                elif data == 'HERE':
                    for i in range(numberOfUsers):
                        if user_online[i]:
                            ans[i] += 1
                else:
                    user_ids = data.split()
                    for user_id in user_ids:
                        id=int(user_id[2:])
                        ans[id] += 1
        
        return ans
```
['Sorting', 'Python3']