如何确定可以通过去除零个或多个字母从单词中得到的最长回文串的长度。
例如:amanQQQapl12345anacaZZZnalpaXXXna67890ma
最长回文串将有21个数字。
如何确定可以通过去除零个或多个字母从单词中得到的最长回文串的长度。
例如:amanQQQapl12345anacaZZZnalpaXXXna67890ma
最长回文串将有21个数字。
这可以通过动态规划来解决。将 d[i, j] 定义为原始字符串中最长回文的长度。
如果 s[i] = s[j],则 d[i, j] = max(d[i+1, j-1] + 2, d[i, j-1], d[i+1, j])。
否则,d[i, j] = max(d[i, j-1], d[i+1, j])。
W中最长的回文是W及其镜像的最长公共子序列。
你可以在O(n²)时间和O(n)空间内计算它,其中n是W的长度,但如果你知道只需要删除一些字符就能使一个回文变得更好,你可以获得更好的复杂度。
回文可以最多有一个奇数计数的字母,即中间的字母,以及任意数量的偶数计数的字母。
您可以计算每个字母的频率。如果对于每个字母来说不是全有或全无的情况,则为每个字母添加计数/2*2,并在任何字母具有奇数计数时添加一。
int d[1000][1000] = {0}; // To store result of previous computation
int computeMaxPalindromeLength(vector<int>& a, int start, int end) {
if(d[start][end] != 0) // If not precomputed, recompute.
return d[start][end];
if(start == end) { // The mid character should be taken as
d[start][end] = 1;
return 1;
}
else if(start == end-1) {
d[start][end] = (a[start] == a[end])?2:1;
return d[start][end];
}
if(a[start] == a[end]) {
d[start][end] = max( 2 + computeMaxPalindromeLength(a, start+1, end-1),
max(computeMaxPalindromeLength(a, start+1, end), computeMaxPalindromeLength(a, start, end-1)));
} else {
d[start][end] = max(computeMaxPalindromeLength(a, start+1, end), computeMaxPalindromeLength(a, start, end-1));
}
return d[start][end];
}
调用上述方法的方式如下:
vector<int>& a; // Convert each character of string to digit if working with alphanumeric characters.
int maxPalindromeLength = computeMaxPalindromeLength(a, 0, a.size()-1);