给定一个很长的产品名称列表,找到第一个唯一的产品名称(恰好出现一次)。您只能在文件中迭代一次。
我正在考虑采用哈希图并将(键,计数)存储在双向链表中。基本上一个链接的哈希图可以任何人优化这个或提供更好的方法
给定一个很长的产品名称列表,找到第一个唯一的产品名称(恰好出现一次)。您只能在文件中迭代一次。
我正在考虑采用哈希图并将(键,计数)存储在双向链表中。基本上一个链接的哈希图可以任何人优化这个或提供更好的方法
由于您只能迭代列表一次,因此您必须存储
值得注意的是,您不必存储多次出现的字符串的相对位置。
你需要
结论:
对字符串集使用链接的哈希集,并使用一个标志来指示它们是否是唯一的。如果您正在为记忆而战,请使用链接的特里。如果链接的 trie 太慢,则将 trie 叶存储在哈希图中以供查找。仅包括链表中的唯一字符串。
总的来说,您的节点可能如下所示:Node:{Node[] trieEdges, Node trieParent, String inEdge, Node nextUnique, Node prevUnique}; Node firstUnique, Node[] hashMap
如果您努力实现易于实施,则可以使用两个哈希集(一个链接)。
以下算法在 O(N+M) 时间内解决它。在哪里
N=字符串数
M = 放在所有字符串中的字符总数。
步骤如下:
`1. Create a hash value for each string`
`2. Xor it and find the one which didn't have a pair`
Xor 有一个有用的属性,如果你执行 a xor a=0 和 b xor 0=b。
为字符串生成哈希值的提示:使用 27 基数系统,并给 aa 值 1,ba 值为 2,依此类推,直到 z 得到 26,所以如果字符串是 "abc",我们计算哈希值如: H=3*(27 power 0)+2*(27 power 1)+ 1(27 power 2) =786 您可以使用模运算符使散列值足够小以适合 32 位整数。如果您这样做留意冲突,这基本上是两个不同的字符串,但由于模运算而获得相同的哈希值。大多数情况下,我猜你不会需要它。
所以计算每个字符串的哈希,然后从第一个哈希开始并保持异或,结果将保存没有一对的字符串的哈希值。 注意:这仅在字符串成对出现时才有用。这仍然是一个好主意,这就是我回答它的原因。
使用链接的哈希图是显而易见的。否则,您可以使用 TreeMap 样式的数据结构,其中字符串按计数排序。因此,一旦您完成读取输入,如果存在唯一字符串,则树的根是唯一的。与链接的哈希映射不同,插入最多需要 O(log n) 而不是 O(n)。您可以阅读 TreeMaps,了解如何将基本的 TreeMap 扩充为您需要的内容。同样在您的链接哈希图中,您可能需要花费 O(n) 才能找到您的第一个唯一键。使用 TreeMap 样式的数据结构,您的查找是 O(1) - 根。即使存在更多唯一键,您遇到的第一个键也将是根。随后的将是根的孩子。