如何将字符串转换为具有最少删除字符串字符数的回文?
Posted
技术标签:
【中文标题】如何将字符串转换为具有最少删除字符串字符数的回文?【英文标题】:how to convert a string to palindrome with minimum number of removals of characters of the string? 【发布时间】:2015-08-08 14:20:21 【问题描述】:假设字符串是“anuja”,输出应该是 2,因为如果我删除字符 'u' 和 'n',给定的字符串变成回文。因此输出应该是最小的删除次数。 更多示例:输入字符串:“ababa” 输出:0(无需移除) 输入字符串:“abcdba” 输出:1(删除“c”或“d”) 请解释一下算法。
【问题讨论】:
不错的问题。到目前为止,您尝试了什么?您的解决方案有什么问题? 【参考方案1】:让dp[i, j] = minimum number of removals needed to convert the substring [i, j] to a palindrome
。我们有:
dp[i, i] = 0 for all i (every single character is a palindrome)
要找到dp[i, j]
,让我们考虑一个随机字符串。我们有两种可能:
第一个和最后一个字符相等:a[i] == a[j]
。在这种情况下,我们可以将问题简化为找到需要删除的最小字符数,以使子字符串[i+1, j-1]
成为回文。
第一个和最后一个字符不相等:a[i] != a[j]
。在这种情况下,我们需要删除其中一个。我们将删除导致我们找到更好解决方案的内容。
所以我们有:
dp[i, j] = dp[i + 1, j - 1] # if a[i] == a[j]
min(dp[i + 1, j], dp[i, j - 1]) + 1 # otherwise
以anuja
为例。我们会得到:
| 1 2 3 4 5
-------------
1 | 0 1 2 2 2
2 | 0 1 2 3
3 | 0 1 2
4 | 0 1
5 | 0
请注意,矩阵是从主对角线开始计算的,然后依次向上计算,对角线平行于主对角线。答案是dp[1, n]
。
这类似于Levenshtein distance,但它只考虑删除。
【讨论】:
@Khushboo 如果答案回答了您的问题,请通过单击左侧的勾号将其标记为已接受。如果您愿意,您也可以通过单击同一位置的向上箭头 (^
) 对其进行投票。
如果你不知道 dp[i][j],你如何计算 dp[i+1][j]
你能解释一下对角线上的0吗
@BaradwajAryasomayajula dp[i, i] = 0 for all i(每个字符都是回文)【参考方案2】:
您可以测量从字符串到其反向(忽略替换)的编辑距离(levenshtein 距离)。所需的值将是该值的一半。
这个问题类似于UVA 10739。这是example implementation。
一个示例实现(适用于您的情况)可以是:
string P, Q;
getline(cin, P);
Q = string(P.rbegin(), P.rend());
int p = P.size(), q = Q.size();
for(int i=0; i<=p; i++) T[i][0] = i;
for(int i=0; i<=q; i++) T[0][i] = i;
for(int i=1; i<=p; i++)
for(int j=1; j<=q; j++)
if (P[i-1] == Q[j-1])
T[i][j] = T[i-1][j-1];
else
T[i][j] = min(T[i-1][j], T[i][j-1]) + 1;
cout << "Case " << tt << ": " << T[p][q]/2 << endl;
【讨论】:
在您链接的问题中,您可以添加、删除和替换字符。在这里您只能删除它们。为什么问题都一样? @IVlad 你是对的,尽管从不同的角度来看,添加和删除是相同的操作。然后只需从重复中删除 T[i-1][j-1] 即可,但您已经在答案中做到了。我将把这个答案留在这里只是因为我认为计算字符串与其反向之间的编辑距离的基本原理很有用:) @Juan Lopes..谢谢你的回答..它有帮助。以上是关于如何将字符串转换为具有最少删除字符串字符数的回文?的主要内容,如果未能解决你的问题,请参考以下文章
一个包含大写和小写字母的字符串,要求在其后面加上最少的字符,使其成为一个回文串。
如何将具有隐藏字符的空白/单元格转换为空值或以其他方式删除隐藏字符
构造回文 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。