📅  最后修改于: 2023-12-03 15:28:38.897000             🧑  作者: Mango
本文将介绍GATE CS 2021设置1的第16个问题,该问题涉及到了编程。
给定一个字符串,为了检查它是否为回文,你可以在任意位置添加任意多个字符。例如,从字符串“racecar”开始,你可以添加一个字符'b'来得到“bracecar”,或添加一个字符'k'来得到“racecark”。你需要找到添加最少的字符来使给定的字符串成为回文。
此问题可以通过动态规划来解决。定义一个二维数组dp[i][j],其中i和j分别表示字符串s的起始位置和终止位置。如果s[i:j]是回文串,则dp[i][j]为true。如果不是,则dp[i][j]为false。
根据回文串的定义,dp[i][j]为true的条件是dp[i+1][j-1]为true且s[i]==s[j]。
对于每个子问题,我们要么在字符串s的前面或后面添加一个字符,要么在字符串s的头或尾添加相同字符,以保持回文性。因此,我们可以通过以下方式来填充dp数组:
最后,我们需要找到最少的插入次数,使得整个字符串成为回文。我们可以使用双指针法得到答案。具体来说,我们设两个指针i和j,i从0开始指向字符串的左端,j从n-1开始指向字符串的右端。如果s[i]==s[j],则将i向右移动一位,j向左移动一位。否则,我们需要使用以下两种操作之一:
将两种操作中插入字符数的较小值加到计数器中,然后更新i和j。
以下是使用Python实现以上算法的代码:
def minInsertions(s: str) -> int:
n = len(s)
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True
for i in range(n - 1, -1, -1):
for j in range(i + 1, n):
if s[i] == s[j]:
dp[i][j] = dp[i + 1][j - 1] if i + 1 < j else True
else:
dp[i][j] = i + 1 < j and dp[i + 1][j - 1]
i, j = 0, n - 1
ans = 0
while i < j:
if s[i] == s[j]:
i += 1
j -= 1
elif dp[i + 1][j] and dp[i][j - 1]:
ans += 1
i += 1
j -= 1
elif dp[i + 1][j]:
ans += 1
i += 1
else:
ans += 1
j -= 1
return ans
以上代码的时间复杂度为$O(n^2)$,空间复杂度为$O(n^2)$,其中$n$为字符串s的长度。