[英]Create palindrome from existing string by removing characters
如何通過刪除零個或多個字母來確定從單詞中獲得的最長回文的長度。
例如: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的長度但是如果您知道只需要刪除幾個字符來制作回文,則可以獲得更好的復雜性。
一個palidrome最多可以有一個奇數計數的字母,即中間字母,以及任意數量的偶數字母。
您可以計算每個字母的頻率。 如果每個字母都不是全部或全部,則為每個字母添加count / 2 * 2,如果任何字母具有奇數,則添加一個。
這是@Rambo的答案的正確實現,以防其他人發現他的答案過於簡潔。 我已經添加了先前結果的緩存,但條件是不同符號的最大數量最多為1000.由於多個分支使用相同的子分支,這提供了顯着的加速。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.