【问题标题】:Way to make this HashMap more efficient使这个 HashMap 更高效的方法
【发布时间】:2014-03-26 21:01:07
【问题描述】:

我有一个 class User 有 3 个对象(?)我不确定术语。

  • 一个 (int) ID 代码
  • 创建用户的 (int) 日期
  • 和一个(字符串)名称

我正在尝试创建一个方法

  • 将用户添加到我的数据结构 (1)
  • 根据 ID 号返回用户名 (2)
  • 返回按日期排序的所有用户的完整列表 (3)
  • 返回名称有特定字符串的用户列表,按日期排序(4)
  • 返回在特定日期之前加入的用户列表 (5)

我根据加入的年份(2004-2014)制作了 10 个数组,然后按日期再次对数组中的元素进行排序(按月和日排序)

我是否正确地认为这意味着方法 (3) 和 (5) 具有 O(1) 时间复杂度,但 (1)、(4) 和 (2) 具有 O(N)

还有另一种数据结构/方法可以让我的所有方法使用O(1)?我反复尝试想出一个,但是方法(2)的包含让我很难过。

【问题讨论】:

  • 基于比较的排序总是 O(N*log N),添加到已经排序的容器是 O(log N)。为避免这种情况,您需要水桶,就像您多年来拥有它们的方式一样。这会用内存换取执行时间。
  • 所有这些都无法使用 O(1)。例如,#4 需要线性搜索。
  • @hyde 我的桶不是基于年份的 10 个数组吗?

标签: java arrays performance sorting hashmap


【解决方案1】:

基于比较的排序总是 O(N*log N),添加到已经排序的容器是 O(log N)。为避免这种情况,您需要水桶,就像您多年来拥有它们的方式一样。这会以内存换取执行时间。

(1) 只有当你只添加东西到HashMaps 时才可能是 O(1)。

如果您有一个单独的 HashMap 将 ID 映射到用户,则 (2) 可以是 O(1)。

(3) 当然是 O(N) 因为你需要列出所有 N 个用户,但是如果你有一个 HashMap ,其中键是日期,值是用户列表,你只需要通过常量 ( 10 年 * 365 天 + 2) 列出所有用户的数组数量。所以 O(N) 与 (1) 仍然是 O(1)。假设用户在一天之内未排序。

(4) 与3基本相同,实现简单,只是打印量少。您也许可以使用 trie 或其他东西来加速 best case,但它仍然是 O(N),因为它将是 N 的某些百分比将匹配。

(5) 同(3),只是可以早点爆发。

【讨论】:

    【解决方案2】:

    您必须做出妥协,并对最常见的操作做出明智的猜测。最常见的操作很有可能是通过 ID 查找用户。因此,HashMap 是理想的结构:它是 O(1),以及插入到地图中。

    要实现按日期排序的用户列表以及给定日期之前的用户列表,最好的数据结构是 TreeSet。 TreeSet 已经排序(因此您的第三次操作将是 O(1),并且可以在 O(log(n)) 时间内返回排序子集。

    但是与 HashMap 并行维护 TreeSet 很麻烦,容易出错,并且会占用内存。插入复杂度将变为 O(log(N))。如果这些不是常见操作,您可以简单地遍历条目并过滤它们/对它们进行排序。绝对忘记你的 10 个阵列。这是不可维护的,TreeSet 是一个更好、更简单的解决方案,不限于 10 年。

    无论您选择哪种数据结构,包含给定字符串的用户列表都是 O(N)。

    【讨论】:

    • 另一种折衷方案:不要使用 TreeSet (这使得添加到 O(log N) 可能会让许多用户感到讨厌),仅在排序顺序为需要,修改后的第一次查找为 O(Nlog N)*.
    【解决方案3】:

    HashMap 不会对任何内容进行排序;它的主要目的/优势是提供接近 O(1) 的查找(您可以将其用于按 ID 进行查找)。如果你需要排序,你应该让类实现Comparable,将它添加到一个List中,然后使用Collections.sort对元素进行排序。

    至于效率:

    1. O(1)
    2. O(1)
    3. O(n log n)
    4. O(n)(至少)
    5. O(n)(或更少,但我认为它必须是 O(n))

    【讨论】:

      【解决方案4】:

      还有另一种数据结构/方法可以让我的所有方法使用 O(1) 吗?

      三个 HashMap。这不是数据库,因此您必须手动维护“索引”。

      【讨论】:

      • 我看到了一个可能的 HashMap。第二个和第三个是什么?
      • 不是相当三个 HashMap,但你会明白的。 UserID->User、UserName->OrderedSet(按创建日期排序)、OrderedSet(按创建日期排序)。可以将其视为手动维护数据库索引,或对数据库引擎进行硬编码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 2011-06-28
      • 2022-01-24
      • 2018-05-19
      • 1970-01-01
      • 2020-11-12
      相关资源
      最近更新 更多