删除字符串中的重复字符而不使用递归

时间:2011-08-05 06:41:08

标签: string complexity-theory

给你一个字符串。开发一个函数来从该字符串中删除重复的字符。字符串可以是任何长度。您的算法必须在太空中。如果您希望可以使用恒定大小的额外空间,而不依赖于字符串大小。您的算法必须具有O(n)的复杂度。

我的想法是定义一个大小为26的整数数组,其中第0个索引对应于字母a和字母z的第25个索引,并将所有元素初始化为0。 因此,我们将遍历整个字符串一次,并在我们遇到一封信时将所需索引的值增加。

然后我们将再次移动字符串,如果所需索引的值为1,我们打印出字母,否则我们不会。

通过这种方式,时间复杂度为O(n),并且无论字符串的长度如何,所使用的空间都是恒定的!

如果有人能提出更高效率的想法,那将会非常有帮助!

2 个答案:

答案 0 :(得分:1)

您的解决方案绝对符合O(n)时间的标准。如果允许的字母表很大(Unicode有超过一百万个字符),而不是一个非常非常大的数组,你可以使用普通的哈希。这是你的算法(未经优化!)Ruby:

def undup(s) 
  seen = Hash.new(0)
  s.each_char {|c| seen[c] += 1}
  result = ""
  s.each_char {|c| result << c if seen[c] == 1}
  result
end

puts(undup "")
puts(undup "abc")
puts(undup "Olé")
puts(undup "asdasjhdfasjhdfasbfdasdfaghsfdahgsdfahgsdfhgt")

它通过字符串进行两次传递,并且由于哈希查找小于线性,所以你很好。

你可以说Hashtable(就像你的数组一样)使用的是常量空间,虽然很大,因为它的大小超出了字母表的大小。即使字母表的大小大于字符串的大小,它仍然算作恒定的空间。

这个问题有很多变化,其中很多很有趣。要真正做到这一点,你可以先排序;这给出了O(n log n)。合并排序有变化,您可以在合并期间忽略重复。事实上,这个“无外部散列表”限制出现在Algorithm: efficient way to remove duplicate integers from an array中(也是标记的面试问题)。

另一个常见的采访问题从一个简单的字符串开始,然后他们说,好吧现在有一百万个字符串,好吧现在是一个有1000亿个字符的字符串,依此类推。当你开始考虑大数据时,事情变得非常有趣。

无论如何,你的想法非常好。它通常可以调整如下:使用集合,而不是字典。通过字符串。对于每个字符,如果它不在集合中,请添加它。如果是,删除它。集合占用的空间更少,不需要计数器,并且如果字母表很小,可以实现为位集,并且该算法不需要两次传递。

Python实现:http://code.activestate.com/recipes/52560-remove-duplicates-from-a-sequence/

答案 1 :(得分:0)

您还可以使用bitset而不是其他数组来跟踪找到的字符。根据允许的字符(a-z或更多),您可以相应地调整位集的大小。这比整数数组需要更少的空间。