【问题标题】:Intersecting list of records相交的记录列表
【发布时间】:2018-06-01 05:31:14
【问题描述】:

我有 2 个列表 -

  • List<String> RecordIdByPriority
  • List<String> RecordId

顾名思义 - 第一个列表包含按优先级插入顺序排列的记录。
这个想法是从第二个列表中找到最高优先级记录的存在。

如果优先级列表包含<A,D,E>,第二个包含<B,E,M> - 预期输出为“E”。

鉴于第二个列表可能很大 - 以最有效的方式实现此目标的数据结构/例程是什么

【问题讨论】:

  • 您没有提供足够的信息来提出好的建议。这取决于这些列表如何随时间变化。 (我假设,你想反复这样做)
  • 第一个“参考”列表是静态的 - 将被用作重复查找新的“第二个”列表
  • Collections::retainAll 是有点矫枉过正的 IMO。只需在RecordIdByPriority 中按优先级顺序循环,其中内部循环RecordId,检查contains() 并在第一个匹配时立即返回。
  • 你只想要一个最高优先级的结果还是所有相交元素的优先级顺序?在后一种情况下,交叉点通常有多大?
  • 预期的输出是找到的单个最高优先级记录。

标签: java algorithm list data-structures


【解决方案1】:

您可以进行一些一次性预处理,将List<String> RecordIdByPriority 转换为HashMap<String, Integer>,将列表中的每个项目映射到其在列表中的位置。在您的示例中 { A -> 0, D -> 1, E -> 2 }。然后单次遍历RecordId 列表,根据哈希图找到最小元素。地图中未找到的元素的隐含优先级为 +infinity。

这意味着您可以在 O(n) 中找到元素,其中 n 是记录 id 列表的长度。

【讨论】:

    【解决方案2】:

    我认为经典循环应该仍然有效。

    public String getHighestPriorityRecord(List<String> recordIdByPriority, List<String> recordId) {
        for (String record : recordIdByPriority) {
            if (recordId.contains(record)) {
                return record;
            }
        }
    
        // Not found
        return null;
    }
    
    • 最佳:O(1)
    • 平均:O(n log n)?
    • 最差:O(n^2)

    如果你想加快速度,那么你可以将recordId 变成HashSet(通过创建HashSet 的新实例),这样contains() 就会变成O(1),这有效地改变了这个算法的最坏情况变成O(n)

    【讨论】:

      猜你喜欢
      • 2015-06-22
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      相关资源
      最近更新 更多