【问题标题】:An efficient algorithm for renaming一种有效的重命名算法
【发布时间】:2013-08-13 15:36:22
【问题描述】:

如果我有一个变量列表, [a, b, a, c, a, a, d, b, c, d, a] 其中顺序很重要, 我必须将它们重命名为整数,我可以使用的最佳算法是什么?

一个简单的算法将是:

  1. 创建一个空的哈希表,HT。
  2. 对于列表中的每个变量,
    1. 如果它没有被索引,则为其分配一个新索引并将(变量,索引)放入HT。
    2. 如果已编入索引,请使用索引。

在上述情况下,解决方案将是 [1, 2, 1, 3, 1, 1, 4, 2, 3, 4, 1]

我关心“n”哈希查找以及随之而来的复杂性。对于非常长的列表(具有更多不同的变量),性能可能非常糟糕。有没有人有更好的算法来处理这个?

请注意,虽然示例使用 ascii 字符,但列表的元素可以是任意字符串,列表的长度可以是任意长(> 100k)等。

【问题讨论】:

  • 我认为哈希表查找是 O(1),除非你遇到冲突
  • 您的意思是O(1) 哈希查找对吗? O(1) for N items 是总算法的效率,而不是哈希查找。
  • 数字必须以1开头并且是连续的吗?还是只是不同?
  • 如果您的变量名称都是单字母名称,您可以使用 int[128] 并使用单字母名称字符的 ASCII 值作为索引。这样可以避免哈希表。
  • 在您的示例中,您可以简单地使用变量的一个字符名称并使用character-'a'+1 作为数字来计算数字。这将产生'a' -> 1, 'b' -> 2 , 'c' -> 3, 'd' -> 4

标签: algorithm hashtable


【解决方案1】:

O(n) 最坏情况下的哈希查找仅在使用简单的冲突解决方案时发生(并且所有项目都映射到相同的哈希值) - 您实际上使用哈希,因为您希望冲突是“罕见的”,因此平均受益于O(1) 查找时间。

因为您必须检查所有变量是否有重复项,所以总体上不会比 O(n) 好。

也许您可以利用其他信息 - 变量名的第一个实例列表是否已排序?如果是,您只需要存储到目前为止遇到的按字典顺序排列的最大变量名称 (vmax),以 null 开头,并在列表元素出现时与它们进行比较。如果被测元素vcur小于或等于vmax,你之前已经看到了变量名,否则增加一个计数器,将vcur与它关联并将vmax设置为vcur

【讨论】:

  • 我必须澄清一下——如果列表中有“n”个项目,那么就有“n”个哈希查找。很抱歉造成混乱。
  • 每次哈希查找仍然有O(1)。并且您的操作总数不会少于 n,因为您必须检查每个变量名称(除非您有额外的信息允许您跳过元素或提前终止)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 2010-12-23
相关资源
最近更新 更多