【问题标题】:Coding: Keep track of last N days of records for each user.编码:跟踪每个用户最近 N 天的记录。
【发布时间】:2017-05-15 19:50:55
【问题描述】:

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

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

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

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

最好的方法是什么?

【问题讨论】:

    标签: algorithm data-structures array-algorithms


    【解决方案1】:

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

    每次访问时,添加一个包含日期/时间的新条目。每天,检查是否有任何客户包含超过 90 天的访问记录。第一个不够老的记录意味着没有更多记录要检查,因此您可以安全地转移到下一个客户。

    希望对您有所帮助!

    【讨论】:

      【解决方案2】:

      为每个客户制作一个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
      

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

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

      【讨论】:

        【解决方案3】:

        你的想法可行,但它真的在空间方面有效吗?

        您的 将是这样的:一个布尔二维向量(您可以将其想象为一个矩阵),其中每一行是用户,每一列是一天(已排序),因此它将包括:

        矩阵大小U x N

        其中 U 是用户数。

        要回答我最初提出的问题,您需要考虑一下这个矩阵会有多密集。如果它会很多,那么你做出了正确的选择,如果没有,那么你就浪费了(很多)空间。您可以在此处查看权衡取舍。

        当然,您必须考虑您的用例。在健身房的例子中,我不认为这会节省空间,因为大多数人不是每天都去健身房(我认为),这将导致矩阵稀疏,这意味着我们浪费了空间。


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

        如果某个用户在某天的列表中,则表示该用户当天去健身房。

        通过这种方法,我们准确地根据需要分配空间,因此它是空间最优的,无论我在矩阵的情况中提到的密度如何。


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

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

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


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

        我也会尝试使用哈希表,它不需要排序并且节省空间 (What is the space complexity of a hash table?)。

        【讨论】:

        • 您如何查看过去 90 天每次去健身房的情况?对于每次访问(可能不是每天),我希望检查从那天起的最后 90 天!
        • 因为天是被排序的,你只需扫描其余的@sad!
        【解决方案4】:

        如何为每个用户设置一个固定大小 (90) 的访问详细信息的队列?您可以为多个用户推广它,关键优势是您不必担心维护最近 90 天的数据。

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

        【讨论】:

          猜你喜欢
          • 2017-08-05
          • 1970-01-01
          • 1970-01-01
          • 2010-12-05
          • 2013-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-01
          相关资源
          最近更新 更多