设计一种算法,用于返回给定时间间隔内独立用户数。

4
一个Web服务器可以接收数百万个用户登录请求。一个用户可以多次登录。设计一种最优算法/数据结构来返回在给定时间间隔内唯一用户的总数,以时间复杂度为考量。
例如:计算t1和t2之间以及t2和t3之间的唯一用户总数。同时考虑重叠时间间隔的总数(t1 = 10am,t2 = 10:15am,t3 = 10:30am,在10:10am到10:20am之间返回用户总数)。
以下是我提出的方案,请大家评论:
我认为使用哈希映射和最小堆的组合是一个好的最优解。
哈希映射 - 键为用户ID,值为指向最小堆中相应节点的节点指针。 最小堆 - 最后登录时间作为键,用户ID作为值。根将是登录时间最早的用户。还要在根节点存储最小堆中节点总数的计数,以便我们可以快速返回计数。
1.当用户登录时。使用用户ID作为键在哈希映射中查找。 a) 如果没有匹配,则将新用户插入哈希映射和最小堆中,并将计数增加到最小堆的根节点。 b) 否则,它是旧用户,更新其最后登录值,并且不要增加最小堆的根节点中的计数。
2.每当我们想要找出t2-t1之间登录的唯一用户时, a. 从堆中提取最小值(根),并检查 当前时间-最后登录时间> t2-t1分钟。如果大于 从哈希映射和最小堆中删除该值。 b. 重复上述步骤(a),直到堆的最小元素满足 当前时间 - 最后登录时间<= t2-t1分钟 c. 返回最小堆的根节点中的计数值。
但我无法确定重叠时间间隔的算法。
1个回答

1
我认为有一种更简单的方法来完成这个任务。将所有数据存储在平衡二叉搜索树中,其中键是登录时间,值是在该时间登录的所有人的列表(假设在同一时刻可能会有多次登录)。从那里,您可以通过查找BST中时间大于或等于T1的最小节点,然后连续计算该节点的中序继承者,直到到达严格在时间T2之后的节点,来找到在时间T1和T2之间登录的所有人。
在平衡BST中进行查找以查找第一个时间大于或等于T1的节点需要O(log n)时间,在多次计算中序继承者需要O(k)时间,其中k是您报告的匹配总数。这总共需要O(log n + k)的时间。由于您必须花费至少O(k)的时间来报告任何算法中的所有匹配登录,因此这具有非常低的开销。
如果您从服务器中以流的形式获取数据(即随着时间的推移始终发生新的登录),您可以使用标准数组来保存所有请求。您只需将新请求附加到数组末尾即可。由于时间始终向前移动,这意味着数组始终是排序的,因此您可以使用二进制搜索查找范围的起点。假设数据没有病态构造,您还可以使用插值搜索使查找时间期望O(log log n)而不是O(log n),在查找k个元素时给出期望的O(log log n + k)查找时间。
至于处理重叠的范围-有标准算法可以将一组范围合并成最小数量的不重叠范围。在进行查找之前,您可以始终应用其中一种技术来处理此情况。
希望这可以帮助您!

请问您能否详细解释一下您的解决方案?我非常感兴趣。我面临着一个类似的问题,我有一个用户表,每个用户都有签到和签退日期时间。我需要找出哪一天酒店有最多的用户。谢谢! - Kumar Vaibhav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接