当前位置: 首页 > news >正文

3433. 统计用户被提及情况

🚀 算法笔记:消息提及计数 (Count Mentions)

1. 题目逻辑核心

本题是一个典型的时间序列模拟问题。其核心挑战在于处理事件的顺序性原子状态更新

核心解题策略

  • 离线处理:预先获取所有事件并进行全局排序,构建统一的时间线。
  • 优先级排序 (Tie-breaking):在同一时刻,状态变更(下线)必须发生在行为判定(发消息)之前。

2. 算法实现分析

A. 事件排序逻辑 (Sorting Criteria)

排序是程序的灵魂,决定了模拟的正确性。

优先级 关键属性 排序规则 原因
1 timestamp 升序 严格遵循时间流逝顺序
2 type OFFLINE 优先 确保 $t$ 时刻下线的人在 $t$ 时刻的 @HERE 统计中被视为“不可见”

C++

// 排序实现代码片段
sort(events.begin(), events.end(), [](const vector<string>& a, const vector<string>& b) {int timeA = stoi(a[1]), timeB = stoi(b[1]);if (timeA == timeB) return a[0] == "OFFLINE"; // OFFLINE 优先return timeA < timeB;
});

B. 状态机设计 (State Management)

与其使用 bool 记录状态并开启定时器,不如记录 “解禁时间点”

  • online_time[i]:存储用户 $i$ 重新变为 ONLINE 的时间戳。
  • 状态转移逻辑
    • 下线online_time[userId] = timestamp + 60
    • 判定current_time >= online_time[userId] $\Rightarrow$ 此时用户是在线的。

C. 消息类型解析 (Dispatching)

  1. ALL:全员 $O(K)$ 累加。
  2. HERE:根据 online_time 过滤在线用户。
  3. id<num>:精准解析。利用 token.substr(2) 剥离前缀,高效转换。

3. C++ 高级语法点复习

std::stringstream

它是处理变长、空格分隔字符串的利器。相比于手动 find 空格,ss >> token 更加安全且易读。

Lambda 表达式

在 sort 中直接定义闭包,避免了外部静态函数的定义,使代码更加内聚。


4. 复杂度深度评估

维度 复杂度 (Big O) 关键因素
时间复杂度 $O(N \log N + M \cdot K)$ $N$=事件数, $M$=消息事件数, $K$=用户总数
空间复杂度 $O(K)$ 需要存储 ansonline_time 两个辅助数组

💡 潜在优化与进阶思考

  1. 性能瓶颈:当 $K$(用户数)极大时,处理 ALL 消息的 $O(K)$ 循环会成为性能灾难。
    • 优化建议:引入一个全局变量 totalAllMentions。当收到 ALL 消息时只更新全局变量,最后结算时合并到每个用户的 ans 中。
  2. 字符串性能stoistringstream 涉及频繁的内存分配。
    • 优化建议:对于性能敏感场景,可改用 std::from_chars(C++17)进行极致的数值转换。

示例代码 (整理版)

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <sstream>using namespace std;class Solution {
public:vector<int> countMentions(int numberOfUsers, vector<vector<string>>& events) {// 1. 离线排序:时间优先,同时间下线优先sort(events.begin(), events.end(), [](const vector<string>& a, const vector<string>& b) {int t1 = stoi(a[1]), t2 = stoi(b[1]);return t1 == t2 ? a[0] == "OFFLINE" : t1 < t2;});vector<int> online_time(numberOfUsers, 0);vector<int> ans(numberOfUsers, 0);// 2. 模拟事件流for (const auto& e : events) {int ts = stoi(e[1]);if (e[0] == "OFFLINE") {online_time[stoi(e[2])] = ts + 60;} else {if (e[2] == "ALL") {for (int i = 0; i < numberOfUsers; ++i) ans[i]++;} else if (e[2] == "HERE") {for (int i = 0; i < numberOfUsers; ++i) {if (ts >= online_time[i]) ans[i]++;}} else {stringstream ss(e[2]);string token;while (ss >> token) ans[stoi(token.substr(2))]++;}}}return ans;}
};
http://www.jsqmd.com/news/115950/

相关文章:

  • Item19--设计 class 犹如设计 type
  • 国外软件,安装即时专业版!
  • Item19--设计 class 犹如设计 type
  • basic_regex
  • c++狼人杀
  • 宠物识别丨基于弱监督学习的宠物视频内容自动标注技术实践 - 指南
  • 朴易天下:道家修行的专业术语分享
  • 个人投资者的落地路径:从“说人话,做量化”到实盘前的三道关
  • 神经网络中的 block 和 module
  • item13--使用对象管理资源
  • 深入解析:蓝桥杯基础算法精讲:模拟与高精度运算实战指南
  • item12-- 拷贝一个对象的所有组成部分
  • sub_match
  • sub_match
  • 抽奖机随机号码生成:3 种算法实现 + 测试全解析(附完整代码)
  • 【零基础精通】Python 字符串全解析:从字符序列到不可变对象的深度构建
  • item14--谨慎考虑资源管理类的拷贝行为
  • python django flask酒店客房管理系统数据可视化分析系统_gq8885n3--论文md5
  • python django flask鹿幸公司员工食堂在线点餐餐饮餐桌预约管理系统的设计与实现_utcnqqs0--论文
  • error_code
  • 虚拟化初步了解
  • Miloco 深度打通 Home Assistant,实现设备级精准控制
  • 好用的大型牛场水滴粉碎机技术强的
  • set_value
  • 日记1217
  • function的类型擦除
  • function bind
  • 日记12,19
  • Item10--令赋值操作符返回一个
  • Item9--绝不在构造和析构过程中调用虚函数