要插入字符串以将其转换为回文的最小字符数

时间:2016-04-27 15:02:25

标签: string algorithm palindrome subsequence

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

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

  1. 让字符串为s1。扭转它。让它成为s2。假设长度为l
  2. 现在找到s1和s2最长的公共子序列。让它的长度为x
  3. 答案是l-x
  4. 例如,假设s1 = abcda。因此s2 = adcba。长度为5.最长公共子序列为长度为3的aba。因此,最小插入次数为5-3 = 2,这是实际答案,结果字符串为a { {1}} dc

    然而,我无法理解它背后的逻辑。任何人都可以向我解释它为什么有效吗?

    并且,有没有bcda解决方案?

1 个答案:

答案 0 :(得分:1)

我不知道是否有O(N)解决方案,但通过与反向比较,您会找到一个回文序列。然后你有l-x个没有配对的字母。 (如果你在镜子的中间有一面镜子,你可以考虑使用一个字母对作为它的反射。例如ab | ba)稍后,通过插入,你只需完成图片。

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

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

s1 = abcddzac

所以s2 = cazddcba。在这里,我们可以将其视为abcdcazd(上半部分)的比较,再加上dzacdcba(后半部分)的比较。我们可以看到两个比较都是相同的,除非它们相互反转,因此它们的连接必须是回文,所以l1和s2必须是回文。

一旦我们得到长度为4的lcs(ad|da),我们就会有4个字母打破对称性(b,c,z,c)。然后我们为它们中的每一个插入一个字母以形成对称,即回文。我们将中间点设置为lcs的中间点,并考虑我们将s1从中间点分成两个,所以我们有

s1 = a bc d|d z a c我们将它从d | d中分成两个,我们最终得到:
d {Ž{1}}℃
a {CB {1}}

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

d {Ž{1}}℃
a {CB {1}}

d {Ž{1}}℃
a {ZCB {1}}

d {ZC {1}}℃
a {ZCB {1}}

d {ZCB {1}}℃
a {ZCB {1}}

d {ZCB {1}}℃
a {ZCB {1}}℃


现在我们从同一点开始它,我们有 c d bcz a zcb d c这是一个回文。

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