leetcode 3433. 统计用户被提及情况 中等

给你一个整数 numberOfUsers 表示用户总数,另有一个大小为 n x 3 的数组 events

每个 events[i] 都属于下述两种类型之一:

  1. 消息事件(Message Event): ["MESSAGE", "timestampi", "mentions_stringi"]
    • 事件表示在 timestampi 时,一组用户被消息提及。
    • mentions_stringi 字符串包含下述标识符之一:
      • id<number>:其中 <number> 是一个区间 [0,numberOfUsers - 1] 内的整数。可以用单个空格分隔 多个 id ,并且 id 可能重复。此外,这种形式可以提及离线用户。
      • ALL:提及 所有 用户。
      • HERE:提及所有 在线 用户。
  2. 离线事件(Offline Event): ["OFFLINE", "timestampi", "idi"]
    • 事件表示用户 iditimestampi 时变为离线状态 60 个单位时间 。用户会在 timestampi + 60 时自动再次上线。

返回数组 mentions ,其中 mentions[i] 表示 id 为 i 的用户在所有 MESSAGE 事件中被提及的次数。

最初所有用户都处于在线状态,并且如果某个用户离线或者重新上线,其对应的状态变更将会在所有相同时间发生的消息事件之前进行处理和同步。

注意 在单条消息中,同一个用户可能会被提及多次。每次提及都需要被 分别 统计。

示例 1:

**输入:**numberOfUsers = 2, events = \["MESSAGE","10","id1 id0","OFFLINE","11","0","MESSAGE","71","HERE"]

输出:2,2

解释:

最初,所有用户都在线。

时间戳 10 ,id1id0 被提及,mentions = [1,1]

时间戳 11 ,id0 离线

时间戳 71 ,id0 再次 上线 并且 "HERE" 被提及,mentions = [2,2]

示例 2:

**输入:**numberOfUsers = 2, events = \["MESSAGE","10","id1 id0","OFFLINE","11","0","MESSAGE","12","ALL"]

输出:2,2

解释:

最初,所有用户都在线。

时间戳 10 ,id1id0 被提及,mentions = [1,1]

时间戳 11 ,id0 离线

时间戳 12 ,"ALL" 被提及。这种方式将会包括所有离线用户,所以 id0id1 都被提及,mentions = [2,2]

示例 3:

**输入:**numberOfUsers = 2, events = \["OFFLINE","10","0","MESSAGE","12","HERE"]

输出:0,1

解释:

最初,所有用户都在线。

时间戳 10 ,id0 离线

时间戳 12 ,"HERE" 被提及。由于 id0 仍处于离线状态,其将不会被提及,mentions = [0,1]

提示:

  • 1 <= numberOfUsers <= 100
  • 1 <= events.length <= 100
  • events[i].length == 3
  • events[i][0] 的值为 MESSAGEOFFLINE
  • 1 <= int(events[i][1]) <= 10^5
  • 在任意 "MESSAGE" 事件中,以 id<number> 形式提及的用户数目介于 1100 之间。
  • 0 <= <number> <= numberOfUsers - 1
  • 题目保证 OFFLINE 引用的用户 id 在事件发生时处于 在线 状态。

分析:先将所有的事件按照发生时间从小到大排序,时间相同的事件,离线排在消息前面处理。同时用一个数组 flag 标识用户是否在线。初始时 flag 全为 -1,代表所有用户都在线;接着当遇到离线事件时,将离线用户 i 的 flagi 改为对应 times+60,表示用户 i 在 times+60 这个时间及之后在线。排序后遍历所有的消息,按照题目要求进行记录即可。

cpp 复制代码
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
typedef struct node
{
    int ind,times;
    char type;
}node;

int cmp(const void *a,const void *b)
{
    node *aa=a;
    node *bb=b;
    if(aa->times!=bb->times)
        return aa->times-bb->times;

    if(aa->type!=bb->type)
        return bb->type-aa->type;

    return aa->ind-bb->ind;
}

int* countMentions(int numberOfUsers, char*** events, int eventsSize, int* eventsColSize, int* returnSize) {
    int *ans=(int*)malloc(sizeof(int)*(numberOfUsers+5));*returnSize=numberOfUsers;
    int flag[numberOfUsers+5];
    node temp[eventsSize+5];
    for(int i=0;i<numberOfUsers;++i)
        ans[i]=0,flag[i]=-1;

    for(int i=0;i<eventsSize;++i)
    {
        temp[i].ind=i,temp[i].type=events[i][0][0];
        temp[i].times=0;
        for(int j=0;events[i][1][j];++j)
            temp[i].times=temp[i].times*10+events[i][1][j]-'0';
    }
    qsort(temp,eventsSize,sizeof(node),cmp);

    for(int i=0;i<eventsSize;++i)
    {
        int pos=temp[i].ind,times=temp[i].times;

        if(events[pos][0][0]=='M')
        {
            if(events[pos][2][0]=='A')
            {
                for(int j=0;j<numberOfUsers;++j)
                    ans[j]++;
            }
            else if(events[pos][2][0]=='H')
            {
                for(int j=0;j<numberOfUsers;++j)
                {
                    if(flag[j]==-1||flag[j]<=times)
                        ans[j]++;
                }
            }
            else
            {
                int id=0;
                for(int j=2;events[pos][2][j];++j)
                {
                    if(events[pos][2][j]==' ')
                        ans[id]++,id=0;
                    else if(events[pos][2][j]>='0'&&events[pos][2][j]<='9')
                        id=id*10+events[pos][2][j]-'0';
                    else continue;
                }
                ans[id]++,id=0;
            }
        }
        else
        {
            int id=0;
            for(int j=0;events[pos][2][j];++j)
            {
                if(events[pos][2][j]==' ')
                    flag[id]=times+60,id=0;
                else if(events[pos][2][j]>='0'&&events[pos][2][j]<='9')
                    id=id*10+events[pos][2][j]-'0';
                else continue;
            }
            flag[id]=times+60,id=0;
        }
    }

    return ans;
}
相关推荐
To_OC5 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC5 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
To_OC6 天前
LC 994 腐烂的橘子:人人都说是 BFS 入门题,我却写了三遍才过
javascript·算法·leetcode
To_OC6 天前
LC 200 岛屿数量:经典 DFS 入门题,我第一次写居然连方向都搞错了
javascript·算法·leetcode
To_OC7 天前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
To_OC9 天前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
To_OC10 天前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
想吃火锅100516 天前
【leetcode】121.买卖股票的最佳时机js/c++
算法·leetcode·职场和发展
凌波粒16 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
退休倒计时16 天前
【每日一题】LeetCode 146. LRU 缓存 TypeScript
算法·leetcode·缓存·typescript