统计在线人数

题面:

       阿里的log文件如下,有三个字段:time(登陆或登出时间点)+uid+login或logout,每条记录按时间顺序排列。问题如下:给定一个时间点T,统计在线人数。

题目来源:http://blog.csdn.net/v_july_v/article/details/11921021

解答:

     一、我们应该先把这个题目用数学语言抽象:

          有n个区间[Si, Ei],每个区间对应一个uid的login和logout,只有logint,没有logout则Ei为无穷大。

          给出区间上的一个点T,求这个T被多少个区间覆盖(对应题面中的在线人数)。

    二、这个问题要分情况讨论:

  1. 只统计一次。那么直接线性的扫一遍即可。
  2. 统计多次,但是统计的Ti已经给出(离线问题),我们可以将时间点Ti排序,然后维护一个用户在线队列Q,每次将Ti的指针和区间指针轮流移动,过程中Q的元素个数即是在线人数,时间复杂度线性,空间复杂度线性。
  3. 统计多次,在线统计(一开始不知道Ti)。 我们观察到,时间点T时刻的在线人数,等于Si<=T的数目,减去Ei<=T的数目。换句话说,就是在T时间之前登陆的人数,减去在T时间之前登出的人数,就得到了当时在线的人数。有了这个结论这道题目就很好解决了,Si,Ei皆已排好序,在原来的序列中二分查找即可,每次时间复杂度为logn。
    上述的分析已经比较完整,但细想还是有更深入的点,比如说这个log超级大,大到内存放不下等等,这个时候其实更需要分而治之的思想,把log文件分块等等,甚至可以用B+树来维护动态的查找操作。

    如果能回答二分查找,你已经是一个优秀的面试者。如果能将log超级大的情况,还有log动态增长的情况一起解决了,恭喜你,直接来我们组吧^ ^


腾讯面试题:求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
回答:
  一天总共有3600*24=86400秒。
  定义一个长度为86400的整数数组intdelta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。
  然后依次读入每个用户的登录时间和退出时间,将与登录时间对应的整数值加1,将与退出时间对应的整数值减1。
  这样处理一遍后数组中存储了每秒中的人数变化情况。
  定义另外一个长度为86400的整数数组intonline_num[86400],每个整数对应这一秒的论坛在线人数。
  假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0]=delta[0]。第n+1秒的人数online_num[n]=online_num[n-1]+delta[n]。
  这样我们就获得了一天中任意时间的在线人数。

你可能感兴趣的:(统计在线人数)