我不知道是否有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
. 在这里,我们可以将其视为abcd
与cazd
(前半部分)的比较加上dzac
与dcba
(后半部分)的比较。我们可以看到两个比较是相同的,只是它们是相反的,所以它们的连接必须是回文,所以 s1 和 s2 的 lcs 必须是回文。
一旦我们有了长度为 4 的 lcs( ad|da
),我们还有 4 个破坏对称性的字母 (b,c,z,c)。然后我们为它们中的每一个插入一个字母以形成对称,即回文。我们将中点设置为 lcs 的中点,并考虑将 s1 从该中点分成两部分,因此我们有
s1 = a
bc d|d
z a
c 我们把它像一根棍子一样从 d|d 分成两半,我们最终得到:
d
z a
c
d
cba
现在我们只需在 lcs 的字母之间填充,使它们相同。在我们的案例中,步骤如下:
d
z a
c
d
cb a
d
z a
c
d
zcb a
d
zc a
c
d
zcb a
d
zcb a
c
d
zcb a
d
zcb a
c
d
zcb a
c
现在我们从同一点解开它,我们有
c a
bcz dd
zcb a
c 这是一个回文。
注意:cddc 也是一个 ldc,但这不会改变步数。