【问题标题】:Possibilities of removing two characters from string to get unique ones从字符串中删除两个字符以获得唯一字符的可能性
【发布时间】:2023-03-25 18:55:01
【问题描述】:

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

例如,对于输入字符串“pizza”,我们有 7 个字符串:“zza”、“iza”、“izz”、“pza”、“pzz”、“pia”、“piz”。

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

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

所以我决定设计更智能的算法,类似于 RLE 压缩,所以我将“pizza”显示为块:1xP、1xI、2xZ、1xA。现在我们可以看到,对于第一个删除字符,它只与我从哪个块中删除字符有关(我们删除了哪个“z”无关紧要)。因此,在第一阶段,我们从例如第一个块中删除一个字符。在第二阶段,我们从仍然存在的块中删除第二个字符。 (我们在每个案例中循环重复过程)。

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

一般而言,算法会因“abababababa...”这样的词而失败(当我们删除第一个“ab”或任何其他相邻词时,我们会得到相同的情况。

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

【问题讨论】:

  • 您可以获得O(n²) 时间和O(n) 空间算法,其中嵌入了两个for 循环来选择要删除的两个字符。
  • 我知道,但是如何处理我提到的这些重复项?
  • 您可以从this 问题中获得灵感。
  • 你能发布你的代码吗?我本来希望您的原始解决方案(带有集合容器)能够正常工作,并且只需要几十兆字节的 RAM。
  • 我弄错了,输入字符串的长度应该等于2400而不是400。但这没关系,因为我无法将所有可能性都存储在内存中。

标签: c++ string algorithm


【解决方案1】:

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

首先,我们将计算不相邻的删除。计算O(n) 时间的计数,表示当前字符的一侧(例如左侧)有多少连续相同字符块,不包括字符所在的块。例如,在“pizza”中,我们将有@987654326 @。当我们遍历时,将array[i-1] 中的数字添加到总数中,但前提是当前字符与前一个字符不同。对于“pizza”,到目前为止,我们将有 `(skip) + 0 + 1 + (skip) + 2 = 3。 (我用了一个数组来演示,虽然我们只需要保留前一个元素。)

现在遍历两个相邻字符的单个窗口,仅当两个字符不等于前两个并且该对中的第二个字符不等于该对之前的字符时才添加1(如“阿巴”)。对于“pizza”,我们得到(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_"

要打印实际的字符串,请遵循相同的想法,即使用上述原则,将相邻对删除与非相邻删除分开枚举。

【讨论】:

  • 算法也应该能够打印这些新词。
  • @AlexanderAnikin 感谢您的评论。我认为我提出的想法很容易适应打印字符串。在相邻对遍历的情况下,我们计算每个实际可能的删除;在不相邻对的情况下,这是一个枚举组合的问题,对于任何连续的相同块,每个删除当然是一个。
  • 感谢您的回答。我实现了你的想法(目前没有打印),它在大多数情况下都有效。不幸的是,有些词我的实现会产生无效的结果。例如“aba”结果 3(正确为 2),“aabaa”结果 3(正确为 4)。所以至少有两个错误。这是代码,我在cmets中标记了我的疑问:pastebin.com/jUjqqCkT
  • @Madras 感谢您的评论,提醒我注意可能的问题。对于"aba",逻辑将是:1 个非相邻对删除,"_b_" + 1 个相邻对删除,"__a"(因为我们添加 1" 仅当两个字符不等于前两个字符和第二个字符时对中的字符不等于对前的字符(如“aba”中的“ba”)。”)。 "aabaa" 的逻辑是:1 个不相邻的:[0,0,1,2,2] => 跳过 + 0 + 0 + 1 + 跳过(即"_ab_a")+ 3 个相邻的"__baa", "a__aa", "aab__" 否?
  • @Madras 您的 pastebin 链接中的一个 cmets 说您不了解某个条件(哪一个?) - 如果有什么我可以更好地解释或澄清的地方,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 2016-01-21
  • 2020-07-31
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
相关资源
最近更新 更多