【问题标题】:Update Value in a Map更新地图中的值
【发布时间】:2015-08-10 04:59:45
【问题描述】:

我正在尝试更新具有多对一关系的 Map 中的值。

| Keys | Values |
| 1    | {1, 2} |
| 2    | {1, 2} |
| 3    | {3}    |

键 1 和 2 指的是同一组。我想合并键 2 和 3 的集合。这样我得到以下结果:

| Keys | Values    |
| 1    | {1, 2, 3} |
| 2    | {1, 2, 3} |
| 3    | {1, 2, 3} |

有没有办法在不得到 O(n) 的情况下做到这一点?

到目前为止我所拥有的:

// Merge sets for keys i and j
Map[Integer, Set[Integer]] map;
map.get(i).addAll(map.get(j));
for(int key : map.get(j)) map.put(key, map.get(i));

【问题讨论】:

  • 所以你想让你的所有键都指向同一个值集?
  • 没错。我想改变 map.get(3) 的引用以引用与 map.get(1) 和 map.get(2) 引用的相同对象。编辑:在这种情况下很容易,因为您可以执行 map.put(3, map.get(1)) 或 map.put(3, map.get(2)),但我想要一个用于合并集合的通用解决方案密钥 j 与密钥 i 的集合。随着不相交的集合变大,它变得很棘手。
  • 这个可行,但我不知道时间复杂度Set<Integer> finalSet = new HashSet<>(); for(int key : map.keySet()) { Set<Integer> value = map.get(key); finalSet.addAll(value); } for(int key : map.keySet()) { map.put(key, finalSet); }

标签: java dictionary hashmap int set


【解决方案1】:

使用 union–find data structure 来解决您的问题。

它支持两个有用的操作:

Find:确定一个特定元素在哪个子集中。Find 通常从这个集合中返回一个作为其“代表”的项目;通过比较两次 Find 操作的结果,可以判断两个元素是否在同一个子集中。

联合:将两个子集连接成一个子集。

仅应用此技术会产生每个 MakeSet、Union 或 Find 操作的最坏情况运行时间 O(log n)

function MakeSet(x)
    x.parent := x

function Find(x)
    if x.parent == x
        return x
    else
        return Find(x.parent)

function Union(x, y)
    xRoot := Find(x)
    yRoot := Find(y)
    xRoot.parent := yRoot

Disjoint-set data structureUnionFind Algorithms 的详细信息

【讨论】:

  • 谢谢。我知道我必须实现一个不相交集结构,但我想看看是否可以使用 HashMap 来保持 O(1) 搜索时间。
【解决方案2】:

你快到了:因为键 1 和 2 已经引用了同一个集合,你只需要从键 3 中添加集合的元素,然后让键 3 引用你的合并结果。

// Merge sets for keys i and j
Map[Integer, Set[Integer]] map;
map.get(i).addAll(map.get(j));
map.put(j, map.get(i));

除非我错过了你问题的一个微妙之处?

编辑:我错过了一个微妙之处:这只适用于将单个元素添加到集合中。如果map.get(j) 有多个元素,我认为没有办法逃避您在问题中建议的循环。

【讨论】:

  • 我坐在这里也是这么想的。不确定我是否遗漏了问题的真正问题。
  • @Pumphouse 不,我错了。这个例子导致了我的错误:使用j = 3,确实没有问题,但是对于更大的样本(例如{1,2,3}和{4,5}),合并确实需要O(n)。我会在我的答案中添加注释。
猜你喜欢
  • 2022-01-08
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 2022-11-19
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多