假设字符串为“anuja”,输出应该是2,因为如果我删除字符'u'和'n',给定的字符串就变成了回文。因此,输出应该是最小的删除次数。
更多例子:
输入字符串:"ababa"
输出:0(不需要删除)
输入字符串:"abcdba"
输出:1(删除'c'或'd')
请解释算法。
令 dp[i, j] = 将子串 [i, j] 转换为回文所需的最小删除次数
。我们有:
dp[i, i] = 0 for all i (every single character is a palindrome)
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距离 ,不过它只考虑了删除操作。
^
)来点赞它。 - IVladstring 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;