【问题标题】:Map for O(1) search for both key and valueMap for O(1) 搜索键和值
【发布时间】:2018-12-04 21:43:34
【问题描述】:

假设我有一堂课:

data class User(val userId: String, val roles: List<String>)

另外,我有一些字符串sessionId,我需要O(1) 时间来通过sessionIduserId 检索数据。

我认为BiMap&lt;String, User&gt; 会解决我的问题,但用户搜索不是O(1),因为我需要先将User 转换为userId

另一种解决方案是覆盖 User 的哈希码/等于,这将只考虑 userId,但这是一个肮脏的 hack。

【问题讨论】:

  • 一个Map&lt;String, int&gt;sessionIduserId 和第二个Map&lt;int, User&gt;userIdUser 怎么样?
  • "按用户搜索不是 O(1),因为我需要先将 User 转换为 userId。"那没有意义。演员表的复杂度为 O(1)。并且有两个 O(1) 操作仍然使整个算法 O(1) 为好。
  • @ErwinBolwidt 我需要迭代所有元素,转换它们(N)然后进行搜索(1),还是我错了?你能详细说明一下吗?
  • 您需要了解有关复杂性的更多信息。即使你顺序组合一千个步骤,每个步骤都是 O(1),得到的算法仍然是 O(1)。
  • 当您想“按用户搜索”以获取会话 ID 时,您的输入究竟是什么?角色列表是搜索输入的必要部分吗?如果不是,那么从 UserId 到 SessionID 的第二个映射是一个有效的解决方案。如果您愿意,您可以将两个映射包装在一个外观类中,以使它们保持同步。或者,如果它符合您的业务逻辑的其余部分,则按照您的建议使用 equals() 也会很好。

标签: java algorithm data-structures kotlin hashmap


【解决方案1】:

User 转换为userIdO(1)。如果您要进行复杂性分析,您只需取指数最大的项,然后丢弃其余项。

如果您执行相同的操作 1000 次,如果您总是执行 1000 次操作,它仍然是 O(1)。如果操作的数量是恒定的并且不取决于输入的大小,则您的复杂度为O(1),但您具有高恒定因子

至于你的问题:

您可以使用任意数量的Maps 来查找您的Users,它仍然是O(1)

val sessionLookup = mapOf<String, User>()
val userIdLookup = mapOf<String, User>()

这里有两个 Maps,它们将会话 ID 和用户 ID 映射到 User 本身。

这里重要的是您为您的Users 和 获取用户它的 sessionId 或 userIdO(1),因为您不必搜索。您将空间复杂度(Maps 的大小)转换为时间复杂度(将 O(n) 搜索转换为 O(1) 查找。

如果你真的想进行渐近复杂度分析,我建议this book

【讨论】:

  • 确实,但是现在出现了两个地图同步的问题,不是吗?
  • 这总是一个权衡。您可以搜索O(n) 或查找O(1)。由于您已经维护了一个 Users 列表(我想),因此维护两个 Maps 也并不难。
猜你喜欢
  • 1970-01-01
  • 2017-02-06
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
  • 2010-11-06
相关资源
最近更新 更多