【问题标题】:Minimum number of characters to be inserted in a string to convert it to palindrome要在字符串中插入以将其转换为回文的最小字符数
【发布时间】:2016-04-27 15:02:24
【问题描述】:

我需要找到将字符串转换为回文所需的最少插入次数。注意:插入可以发生在任何地方、末尾或内部。如果只是在最后,我们有一个问题here

所以我发现这可以通过这个简单的技巧在O(N**2)时间完成:

  1. 让字符串为 s1。扭转它。让它成为s2。假设长度是l
  2. 现在找到 s1 和 s2 的最长公共子序列。让它的长度为x
  3. 答案是l-x

例如,假设s1 = abcda。因此s2 = adcba。长度为 5。最长的公共子序列是长度为 3 的 aba。因此,插入的最小数量是 5-3 = 2,这是实际答案,结果字符串 - adc bcda.

但是,我无法理解其背后的逻辑。谁能向我解释它为什么有效?

还有,有没有可能的O(N) 解决方案?

【问题讨论】:

标签: string algorithm palindrome subsequence


【解决方案1】:

我不知道是否有O(N) 解决方案,但是通过与相反的比较,您会发现一个子序列是回文。然后你有未配对的l-x 字母。 (如果你在单词的中间有一面镜子,你可以将一个字母的对视为它的反射。例如 ab|ba)稍后,通过插入,你就完成了图片。

现在,首先,我们如何找到两个字符串共有的(最大)子序列?有一个多项式算法可以找到它,请参见此处 https://en.wikipedia.org/wiki/Longest_common_subsequence_problem

当我们试图找到 s1 和 s2(s1 的反向)之间的最长公共子序列(lcs)时,我们实际上在 s1 的前半部分和 s2 的前半部分之间找到了 lcs,同时也在 s1 的后半部分和 s2 的后半部分之间找到了 lcs。 假设

s1 = abcddzac

所以 s2 = cazddcba。在这里,我们可以将其视为abcdcazd(上半场)的比较加上dzacdcba(下半场)的比较。我们可以看到两个比较是相同的,只是它们是相反的,所以它们的连接必须是回文,所以 s1 和 s2 的 lcs 必须是回文。

一旦我们有了长度为 4 的 lcs(ad|da),我们还有 4 个破坏对称性的字母 (b,c,z,c)。然后我们为它们中的每一个插入一个字母以形成对称,即回文。我们将中点设置为 lcs 的中点,并考虑将 s1 从该中点分成两部分,因此我们有

s1 = a bc d|d z a c 我们把它像一根棍子一样从 d|d 分成两半,我们最终得到:
dzac
dcba

现在我们只需在 lcs 的字母之间填充,以使它们相同。在我们的案例中,步骤如下:

dzac
dcba

dzac
dzcba

dzcac
dzcba

dzcbac
dzcba

@ 987654354@zcbac
dzcbac


现在我们从同一点拆开它,我们有
cabczddzcbac 这是一个回文。

注意:cddc 也是一个 ldc,但这不会改变步数。

【讨论】:

  • 你能详细解释一下吗?我还不清楚。
  • 好的,这部分我说对了,字符串的 LCS 及其反向必须是回文。因此,对于您的示例,回文是长度为 4 的 adda。但是您如何将剩余的 4 个字符插入其中以保持回文状态?
  • 我编辑了那部分,但那时你已经有了答案l-x
  • 对不起,我还是没听懂。你给出的单词顺序是什么?它以dzaxdcba 开头,它们是字符串的两半,没关系。然后?您按顺序插入 b、c、z 和 c。谁决定顺序(我猜没有一个)?你在哪里插入它,为什么?
  • 没关系。在序列中,每两个是我们希望回文相等的一半。是的,没有插入顺序。插入在这里是微不足道的。在示例中,da 是来自 lcs 的两个字母。在一种情况下是 z ,在另一种情况下是 cb 。我们希望他们最终是平等的。我们有dzadbca 所以我们可以到达dzbca, dbzca,dbcz@9876。他们都没事。然后在a 之后,我们在一种情况下有c,在另一种情况下没有,所以我们只插入c,这就是ac。最后我们有dzbcac(后半部分),它的反面是cacbzd(前半部分),新的s1长度为12
猜你喜欢
  • 2015-05-24
  • 2012-05-30
  • 2019-08-06
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
  • 2016-02-16
相关资源
最近更新 更多