创建一个“绑定地图”是允许O(1)随机查找地图的好主意吗?

时间:2011-03-17 15:24:19

标签: language-agnostic data-structures random map hashmap

在很多情况下,您必须选择包含数千或数百万个元素的地图的随机条目。例如,显示随机引用,定义或客户反馈。为了清楚起见,我将在本文的其余部分假设我正在处理一个字典映射,其中键字符串是单词,值字符串是它的定义。

这种问题的暴力方法就是这样的。

// Bruteforce approach
x = new integer between 0 and the number of entries in the map
iterate x times
return the element

我觉得使用暴力方法不仅慢而且耗时,而且很愚蠢。

为什么我必须迭代数千个元素才能找到我不是特别需要的东西?

避免暴力并进行O(1)随机查找的唯一方法是使用整数作为地图的关键,因为有两点:

  • 我们可以获得的唯一随机对象是整数
  • 在地图中进行O(1)查找的唯一方法是知道密钥。

但是因为你只能有一个键,如果你把一个整数作为你的键,那么就不能用O(1)查找给定单词的定义,这就是在第一名。

我发现这样做的方法是声明第二张地图,即“绑定”地图,它只是将字典的每个键绑定到一个整数。

基本上,你最终有两张地图:

  • 您将单词作为键和定义作为值的字典
  • bindingMap,其中整数为键,单词为值

因此,如果您想要检索给定单词的定义,请执行以下操作:

dictionary.get("hello");

如果你想要检索一个随机单词,你可以这样做:

dictionary.get(bindingMap.get(myRandomNumber));

优点:

  • 允许O(1)查找和随机访问

缺点:

  • 空间复杂度为O(2n)而不是O(n)......这仍然是O(n)...

您如何看待这种方法?你有没有看到更好的方法呢?

1 个答案:

答案 0 :(得分:0)

如果您愿意接受O(lg n)查找而不是O(1)查找,您可能需要考虑将元素存储在order statistic tree中,这是一个支持查找的修改后的平衡二叉搜索树O(lg n)中的插入和删除,以及在位置k中查询O(lg n)时间内任意k的元素的能力。

如果你使用字符串作为键,你也可以考虑修改结构,以便你有一个“order statistic trie”,你可以将字符串存储在一个增加了每个分支的元素数量的trie中。这样可以非常快速地查找元素,同时仍然支持快速随机查询。

最后,如果你想采用双映射方法,可以考虑用标准数组或动态数组替换最后一个映射;它的空间效率更高。

希望这有帮助!