【问题标题】:HashMap with O(log(N)) time complexity operations具有 O(log(N)) 时间复杂度操作的 HashMap
【发布时间】:2020-12-28 07:22:54
【问题描述】:

我对 CodeSignal 进行了测试,但无法解决此问题。

创建一个允许以下操作的数据结构。
insert x y - 插入带有键 x 和值 y 的对象。
get x - 返回带有键 x 的对象的值。
addToKey x - 将 x 添加到地图中的所有键
addToValue y - 将 y 添加到地图中的所有值。
每个操作的时间复杂度应该是O(log(N))

我能够在 Java 中使用数组和 LinkedList 制作哈希映射。但是我无法将时间复杂度提高到 O(log(N))。 在我的实现中,插入和获取的时间复杂度为 O(1)(最坏情况下为 O(N))。 addToKey 和 addToValue 的时间复杂度是 O(N),因为我必须迭代所有元素来修改键和值。
什么是适合这个问题的数据结构?

【问题讨论】:

  • 键和值是数字吗?如果不是,那么将 x/y 添加到所有键/值意味着什么?
  • 这是一个 HashMap 问题,但这是一个 BST 问题。创建一个具有 2 个 int、key 和 value 的节点,并通过比较键创建一个 BST
  • "addToValue y - 将 y 添加到地图中的所有值。" 我怀疑这可以在不到 O(N) 的时间内完成,或者如果这可能是 O(1)您将附加值的总和分别保存在另一个变量中
  • @Cid 即使我也这么想,密钥必须是唯一的数字,所以应该只更新 1 个密钥。 hashMap 中的 key 不能超过一个

标签: java algorithm kotlin data-structures


【解决方案1】:

在 The Vee 和 Tom Elias 的帮助之后更正了答案。

您不能通过迭代所有元素来实现 addToKeyaddToValue,因为正如您所意识到的那样,这需要线性时间。

相反,您可以保留一个 keyDeltavalueDelta int 实例变量,它们分别保存应该添加到每个键和值的值(或所有值的总和)。这是假设 addToKeyaddToValue 应该向键或值添加一个数值。

addToKeyaddToValue 只需要更新那些实例变量,这将需要O(1)

get(x) 操作将搜索键 x - keyDelta 并在添加 valueDelta 后返回其对应的值。

请注意,add(x,y) 也需要更改,因为添加到 Map 的键值对不应受到先前对 addToKeyaddToValue 的调用的影响。如果insert(x,y) 实际将x - keyDelta, y - valueDelta 对插入到地图中,则可以实现这一点。

如果您使用 TreeMap 实现键到值的映射,getinsert 将采用 O(logN)

【讨论】:

  • 嗯,原则上你可以从新添加的对中减去当前的 keyDelta 和 valueDelta 来保存这种方法。
  • 我的意思是在他们插入的那一刻,对不起。这样,它们的行为将与所有剩余操作中已有的内容保持一致。
  • 他是对的,而不是 (key,value) 一直插入 (key-delta, value-delta)。当您“获得”时,您总是返回(价值旧增量+新增量)。 boker tov ;)
  • 是的,这可能有效。感谢 Vee 和汤姆
  • @MaLong 只需使用java.util.TreeMap
猜你喜欢
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
相关资源
最近更新 更多