2025-12-12 Daily Challenge

Today I have done leetcode's December LeetCoding Challenge with cpp.

December LeetCoding Challenge 12

Description

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"]
    <ul>
    	<li>This event indicates that a set of users was mentioned in a message at <code>timestamp<sub>i</sub></code>.</li>
    	<li>The <code>mentions_string<sub>i</sub></code> string can contain one of the following tokens:
    	<ul>
    		<li><code>id&lt;number&gt;</code>: where <code>&lt;number&gt;</code> is an integer in range <code>[0,numberOfUsers - 1]</code>. There can be <strong>multiple</strong> ids separated by a single whitespace and may contain duplicates. This can mention even the offline users.</li>
    		<li><code>ALL</code>: mentions <strong>all</strong> users.</li>
    		<li><code>HERE</code>: mentions all <strong>online</strong> users.</li>
    	</ul>
    	</li>
    </ul>
    </li>
    <li><strong>Offline Event:</strong> <code>[&quot;OFFLINE&quot;, &quot;timestamp<sub>i</sub>&quot;, &quot;id<sub>i</sub>&quot;]</code>
    <ul>
    	<li>This event indicates that the user <code>id<sub>i</sub></code> had become offline at <code>timestamp<sub>i</sub></code> for <strong>60 time units</strong>. The user will automatically be online again at time <code>timestamp<sub>i</sub> + 60</code>.</li>
    </ul>
    </li>
    

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.

 

Example 1:

Input: numberOfUsers = 2, events = [["MESSAGE","10","id1 id0"],["OFFLINE","11","0"],["MESSAGE","71","HERE"]]

Output: [2,2]

Explanation:

Initially, all users are online.

At timestamp 10, id1 and id0 are mentioned. mentions = [1,1]

At timestamp 11, id0 goes offline.

At timestamp 71, id0 comes back online and "HERE" is mentioned. mentions = [2,2]

Example 2:

Input: numberOfUsers = 2, events = [["MESSAGE","10","id1 id0"],["OFFLINE","11","0"],["MESSAGE","12","ALL"]]

Output: [2,2]

Explanation:

Initially, all users are online.

At timestamp 10, id1 and id0 are mentioned. mentions = [1,1]

At timestamp 11, id0 goes offline.

At timestamp 12, "ALL" is mentioned. This includes offline users, so both id0 and id1 are mentioned. mentions = [2,2]

Example 3:

Input: numberOfUsers = 2, events = [["OFFLINE","10","0"],["MESSAGE","12","HERE"]]

Output: [0,1]

Explanation:

Initially, all users are online.

At timestamp 10, id0 goes offline.

At timestamp 12, "HERE" is mentioned. Because id0 is still offline, they will not be mentioned. mentions = [0,1]

 

Constraints:

  • 1 <= numberOfUsers <= 100
  • 1 <= events.length <= 100
  • events[i].length == 3
  • events[i][0] will be one of MESSAGE or OFFLINE.
  • 1 <= int(events[i][1]) <= 105
  • The number of id<number> mentions in any "MESSAGE" event is between 1 and 100.
  • 0 <= <number> <= numberOfUsers - 1
  • It is guaranteed that the user id referenced in the OFFLINE event is online at the time the event occurs.

Solution

vector<string> split(const string &s, char spliter = ' ') {
  vector<string> result;
  for(int i = 0; i < s.length(); ++i) {
    string st;
    while(i < s.length() && s[i] != spliter) {
      st += s[i];
      i += 1;
    }
    if(st.size()) result.emplace_back(st);
  }
  return result;
}
class Solution {
  using pi = pair<int, int>;
  int getId(const string &id) {
    return stoi(id.substr(2));
  }
  const string MSG = "MESSAGE";
  const string OFF = "OFFLINE";
  const string ALL = "ALL";
  const string HERE = "HERE";
public:
  vector<int> countMentions(int n, vector<vector<string>>& events) {
    priority_queue<pi, vector<pi>, greater<pi>> pq;
    vector<int> answer(n);
    vector<bool> online(n, true);

    sort(events.begin(), events.end(), [&](const vector<string> &a, const vector<string> & b) {
      int ta = stoi(a[1]);
      int tb = stoi(b[1]);
      return ta < tb || (ta == tb && a[0] == OFF && b[0] != OFF);
    });
    for(const auto &e : events) {
      int time = stoi(e[1]);
      while(pq.size() && time >= pq.top().first) {
        online[pq.top().second] = true;
        pq.pop();
      }
      if(e[0] == MSG) {
        if(e[2] == ALL) {
          for(auto &c : answer) c += 1;
        } else if(e[2] == HERE) {
          for(int i = 0; i < n; ++i) {
            if(online[i]) answer[i] += 1;
          } 
        } else {
          auto ids = split(e[2]);
          for(auto id : ids) {
            answer[getId(id)] += 1;
          }
        }
      } else {
        int id = stoi(e[2]);
        online[id] = false;
        pq.push({time + 60, id});
      }
    }
    return answer;
  }
};

// Accepted
// 673/673 cases passed (32 ms)
// Your runtime beats 60.99 % of cpp submissions
// Your memory usage beats 26.95 % of cpp submissions (53.4 MB)