编码:跟踪每个用户最近 N 天的记录。

Coding: Keep track of last N days of records for each user.

我正在解决一个有趣的问题,其中对于每个用户,我想保留他最后 N 天的 activity。这可以应用于许多用例,一个这样简单的用例是:

对于每个用户 - 用户可以在某一天随机来健身房 - 我想获得他在过去 90 天内去健身房的总次数。

这对我来说是一个棘手的问题。

我的想法:我想存储一个向量,其中每个条目将确定一天,然后一个布尔值可能代表他的访问。要计数,只需对数组中的该部分进行线性处理就足够了。

最好的方法是什么?

根据您需要的复杂程度,存储每次客户访问的简单数组就足够了。

每次访问时,添加一个包含 date/time 的新条目。每天,运行 检查是否有任何客户包含超过 90 天的访问记录。第一个不够旧的记录意味着没有更多的记录可以检查,所以你可以安全地移动到下一个客户端。

希望对您有所帮助!

您的想法会奏效,但它真的 space 有效吗?

你的 会是这样的:一个布尔二维向量(你可以把它想象成一个矩阵),其中每一行是一个用户,每一列是一天(排序),所以包括:

matrix of size U x N

其中 U 是用户数。

要回答我最初提出的问题,您需要考虑这个矩阵密集的程度。如果它会很多,那么你做出了正确的选择,如果不是,那么你浪费了(很多)space。您可以在此处查看权衡。

当然,您必须考虑您的用例。在健身房的例子中,我认为这不会 space 有效,因为 most 人不是每天都去健身房(我认为),这将导致矩阵稀疏,这意味着我们浪费了 space.


另一个想法是使用单个矢量 os 大小 N,其中对日期进行排序。每个条目都是一个链表,其中每个节点都是一个用户。

如果某个用户出现在某一天的列表中,则说明他那天去了健身房。

通过这种方法,我们根据需要精确分配了space,所以它是space最优的,不管我在矩阵案例中提到的密度如何.


然而,是这样吗?不,当然不!我讨论了space,但是时间效率呢?例如,搜索是我们希望我们的数据结构支持的一种常用方法,如果我们希望它更快!

在矩阵的情况下,搜索将是一个 O(1) 操作,这很不错,因为访问矩阵是一个常量操作。

然而,在矢量+列表的情况下,搜索将花费 O(L),其中 L 是我们的矢量总共具有的列表的平均大小。


那是哪一个?这取决于您的应用!

我也会尝试哈希表,它不需要排序并且 space 高效 (What is the space complexity of a hash table?)。

为每个用户设置一个固定大小 (90) 的访问详细信息的 Queue 怎么样?您可以将其概括为多个用户,主要优势是您不必担心维护最近 90 天的数据。

如果需要,您可以将队列转储到列表或数组并在 O(n) 中保留。正如您所提到的,no.of 存在的检查也将是 O(n)。

为每个客户创建一个 Queue data structure,其中包含带有访问日期的元素。 当客户访问健身房时,只需添加当前日期

Q[ClientIdx].Add(Today)

当您需要为他获取曲目时:

while (not Q[ClientIdx].Empty) and (Today - Q[ClientIdx].Peek > 90) 
    Q[ClientIdx].Remove  //dequeue too old records
VisitCount = Q.Count

如果标准队列不可用,您可以使用多种语言的标准队列实现或基于 array/list 的简单自己的实现。

请注意,每条记录都添加和删除一次,因此每个 add/count 操作的分摊复杂度为 O(1)