从字符串中删除两个字符以获得唯一字符的可能性

时间:2016-10-31 20:21:45

标签: c++ string algorithm

在删除两个字符后,我需要获取一些唯一的字符串。算法还应该提供打印这些新单词的可能性。输入字符串由' a'到' z'仅限ASCII字符。

例如输入字符串" pizza"我们有7个字符串:" zza"," iza"," izz"," pza"," pzz", " pia"," piz"。

我的首要任务是算法的高效率。

我放弃了使用set容器的想法,以避免由于巨大的内存复杂性造成的重复(对于2400个字符的输入字符串,我填充整个RAM和交换)。这个解决方案似乎也没那么快。

所以我决定设计类似于RLE压缩的更智能的算法,所以我展示了#34; pizza"作为块:1xP,1xI,2xZ,1xA。现在我们可以看到,对于第一个删除字符,只关注我删除字符的哪个块(我们删除了哪个' z并不重要)。所以在第一阶段,我们从例如第一个块中删除一个字符。在第二阶段,我们将从仍然存在的块中删除第二个字符。 (我们在每个案例的循环中重复过程。)

问题是此解决方案适用于删除一个字符。但对于两个字符,它可能会产生重复。例如输入" aba"我们有块1xA,1xB,1xA:我们从第一个块中删除一个字符,我们得到1xB,1xA。接下来,我们将从第一个现有块(1xB)中删除下一个字符,然后获得1xA。下一个算法进入原始输入字符串的下一个块(1xB)并删除属于该块的一个字符,我们得到2xA。接下来我们将从现有块中删除第二个字符(我们只有一个块),然后我们得到1xA。在这里,我们有重复。

一般来说,算法会失败,并且#abababababa ..." (当我们首先删除" ab"或任何其他邻居时,我们会得到同样的情况。

我需要建议如何巧妙地处理这种重复。也许你对算法有完全不同的想法。

1 个答案:

答案 0 :(得分:5)

我认为有一个O(n)时间,O(1)空间解决方案用于计算数字(O(n^3)当然对于实际字符串的最坏情况)。对于删除的任何一个字符,只有当删除的字符来自相同字符的相同连续块时,才会认为字符串与另一个字符相等。例如," piz_a"和" pi_za"。

首先,我们计算非相邻的删除。计算O(n)时间内的计数,表示当前字符的一边(左边)有多少个连续相同的字符块,不包括字符所在的块。例如,在"披萨&#34中;,我们会[0,1,2,2,3]。在我们遍历时,将array[i-1]中的数字添加到总数中,但前提是当前字符与前一个字符不同。对于" pizza",到目前为止,我们将`(跳过)+ 0 + 1 +(跳过)+ 2 = 3。 (我使用数组进行演示,虽然我们只需要保留前一个元素。)

现在遍历两个相邻字符的单个窗口,仅当两个字符不等于前两个字符时才添加1,并且该对中的第二个字符不等于该对之前的字符(例如&#34 ; ba" in" aba")。对于"披萨",我们得到(skip) + 1 + 1 + 1 + 1 = 4,其中非相邻删除的数量总和为7.

对于" ababab",对遍历只计算第一个" ab"删除,而非相邻对遍历将计为:"_b_bab", "_ba_ab", "a_a_ab", "_bab_b", "a_ab_b", "ab_b_b", "_baba_", "a_aba_", "ab_ba_", and "aba_a_"

要打印实际的字符串,请遵循相同的想法,使用上述原则分别列出与非相邻的相邻对删除。