3433.统计用户被提及情况

题目描述

有一个聊天系统,共有 numberOfUsers 个用户,编号从 0numberOfUsers - 1。所有用户初始时都处于在线状态

系统会记录一系列事件,每个事件按发生时间顺序给出,但输入数组可能未排序。每个事件是以下两种类型之一:

1. 消息事件("MESSAGE")

格式:["MESSAGE", "timestamp", "mentions"]

  • timestamp:事件发生的时间戳(正整数)
  • mentions:一个字符串,表示此次消息中提及的用户,有三种可能:
    • "ALL":提及所有用户(无论是否在线)
    • "HERE":仅提及当前在线的用户
    • "id0 id1 id2 ...":空格分隔的用户 ID 列表(如 "id1 id0 id1"),可能包含重复或离线用户

注意:提及列表中的每个 idX 都会被单独计数(重复出现则多次计数)。

2. 离线事件("OFFLINE")

格式:["OFFLINE", "timestamp", "userId"]

  • 用户 userIdtimestamp 时刻开始离线 ,并持续 60 个单位时间
  • 用户将在 timestamp + 60 时刻自动恢复在线
  • 若用户已在离线状态,新的 OFFLINE 事件会覆盖之前的离线结束时间

重要规则

  • 多个事件可能具有相同的时间戳 。此时必须先处理所有 "OFFLINE" 事件,再处理 "MESSAGE" 事件
  • 用户是否在线,仅取决于当前时间 t 与该用户的最新离线结束时间
    • 当前时间 t >= 离线结束时间 → 在线
    • 否则 → 离线

要求

请返回一个长度为 numberOfUsers 的整数数组 result,其中 result[i] 表示用户 i 在所有消息中被提及的总次数。

java 复制代码
import java.util.*;

public class Solution {
    public int[] countMentions(int numberOfUsers, List<List<String>> events) {
        List<List<String>> list = new ArrayList<>(events);
        Collections.sort(list, (a, b) -> {
            int timeA = Integer.parseInt(a.get(1));
            int timeB = Integer.parseInt(b.get(1));
            if (timeA != timeB) {
                return Integer.compare(timeA, timeB);
            }
            String typeA = a.get(0);
            String typeB = b.get(0);
            if ("OFFLINE".equals(typeA) && "MESSAGE".equals(typeB)) return -1;
            if ("MESSAGE".equals(typeA) && "OFFLINE".equals(typeB)) return 1;
            return 0;
        });

        int[] mentions = new int[numberOfUsers];
        int[] onlineUntil = new int[numberOfUsers]; // 初始为 0,表示一开始就在线

        for (List<String> e : list) {
            String type = e.get(0);
            int t = Integer.parseInt(e.get(1));
            String data = e.get(2);

            if ("OFFLINE".equals(type)) {
                int uid = Integer.parseInt(data);
                onlineUntil[uid] = t + 60;
            } else { // MESSAGE
                if ("ALL".equals(data)) {
                    for (int i = 0; i < numberOfUsers; i++) {
                        mentions[i]++;
                    }
                } else if ("HERE".equals(data)) {
                    for (int i = 0; i < numberOfUsers; i++) {
                        if (onlineUntil[i] <= t) {
                            mentions[i]++;
                        }
                    }
                } else {
                    for (String token : data.split(" ")) {
                        if (token.startsWith("id")) {
                            int uid = Integer.parseInt(token.substring(2));
                            mentions[uid]++;
                        }
                    }
                }
            }
        }

        return mentions;
    }
}
java 复制代码
public static void main(String[] args) {
    Solution sol = new Solution();
    int n = 2;
    String[][] events = {
        {"MESSAGE", "10", "id1 id0"},
        {"OFFLINE", "11", "0"},
        {"MESSAGE", "71", "HERE"}
    };

    int[] res = sol.countMentions(n, events);
    System.out.println(Arrays.toString(res)); // 输出: [2, 2]
}
相关推荐
啷里格啷几秒前
第三章 Fast-DDS核心源码导读与流程拆解
后端·架构
爱编程的小新☆14 分钟前
Spring-AI入门
java·后端·spring
蝎子莱莱爱打怪15 分钟前
👋🏻👋🏻再见,拉勾网——那个"最懂互联网人"的招聘平台倒了😭
前端·后端·招聘
用户2986985301420 分钟前
Java 获取 Word 文档中修订记录的实现方法
java·后端
TheRouter43 分钟前
PromptCaching 工程实践:把LLM 调用成本砍掉80%
java·后端·spring·ai
Gopher_HBo1 小时前
Go pprof性能剖析
后端
IT策士1 小时前
Django 从 0 到 1 打造完整电商平台:个人中心与用户信息修改
后端·python·django
小明同学011 小时前
C++后端项目:统一大模型接入 SDK(五)
服务器·c++·后端·计算机网络·语言模型
SimonKing1 小时前
IP定位库的完美替代品:ip2region,开源、免费!
java·后端·程序员
XiYang-DING1 小时前
【Spring】Lombok
java·后端·spring