在字符串中查找第一个非重复字符

时间:2013-09-19 22:34:24

标签: c arrays string algorithm hashmap

我在接受采访时被问到这个问题。我的回答是:“创建一个大小为26的数组。遍历每个字符的字符串并对数组中的字符进行计数。通过在字符串中再次遍历检查第一个非重复字符,并检查数组是否重复该字符。”如果字符串包含大量字符集(如10000种字符而不是26种字母表),该怎么办?

4 个答案:

答案 0 :(得分:2)

您可以使用更少的内存来实现原始算法。由于您不关心字符在1以上重复的次数,因此字母表中每个字符只需要2位。递增一个已经大于1的值时,只需保留该值。算法的其余部分保持不变。

如果内存不是限制,则有一种更快的算法,不需要再通过字符串。允许字母表中的每个字母用ListNode表示。然后有两个列表,list1list2,从空开始。 list1包含仅发生过一次的字母,list2包含多次出现的字母。对于输入字符串中的每个字母,请获取相应的ListNode,例如node。如果node不在任何一个列表中,请将其放在list1的末尾。如果node已经在list1中,请将其取出,并将其放入list2。处理输入字符串后,如果list1为空,则不存在非重复字符。否则,与list1中的第一个节点对应的字符是第一个非重复字符。

关注this link to IDEONE以实现基于列表的算法。

答案 1 :(得分:1)

你给了蛮力的回答。一个聪明的解决方案保留了字母表大小的数组,我们将其称为 x ,每个项目最初为-1。然后通过弦一次;如果当前字符的 x - 值为-1,则将其更改为当前字符的索引,否则如果当前字符的 x - 值大于0 ,将其更改为-2。在字符串的末尾,检查 x 数组中的每个位置,跟踪最小的正值和关联的字符。我在my blog的Scheme中实现了该算法。

答案 2 :(得分:0)

  • 您可以使用树状数据结构而不是数组。
  • 如果我们的字符串不是太长,请逐个字符循环字符串并检查,是否设法再次找到它。缺点:在最坏的情况下n ^ 2运行时
  • 为第一遍建立每个字符的哈希值,然后单独检查每个桶。应该与上面的方法结合使用,我不确定它是否会显着降低运行时间 - 这取决于你的真实世界数据。

答案 3 :(得分:0)

  1. 开始逐个字符地读取字符串
  2. 将每个字符放在HashMap中
  3. 返回有冲突的第一个字符
  4. 优点: 您不需要提前创建BitMap / Bit-Array

    缺点: 如果HashMap没有遇到重复字符(或者没有重复字符),它可以增长到字符串中的字符数。