騰訊筆試程式設計題:構造迴文(C++)
阿新 • • 發佈:2019-02-20
題目:
給定一個字串s,你可以從中刪除一些字元,使得剩下的串是一個迴文串。
如何刪除才能使得迴文串最長呢?
輸出需要刪除的字元個數。
輸入描述:
輸入資料有多組,每組包含一個字串s,且保證:1<=s.length<=1000.
輸出描述:
對於每組資料,輸出一個整數,代表最少需要刪除的字元個數。
輸入例子:
abcda
輸出例子:
2
2
分析:
比較簡單的想法就是求原字串和其反串的最大公共子串的長度,然後用原字串的長度減去這個最大公共子串的長度就得到了最小編輯長度。
(注:最大公共子串並不一定要連續的,只要保證出現次序一致即可看作公共子串)
可以使用 Needleman/Wunsch演算法 ,犧牲記憶體換取簡單的程式碼和CPU時間。
答案:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int MAX = 1001;
int MaxLen[MAX][MAX]; //最長公共子序列,動態規劃求法
int maxLen(string s1, string s2){
int length1 = s1.size();
int length2 = s2.size();
for (int i = 0; i <= length1; ++i)
MaxLen[i][0] = 0;
for (int i = 0; i <= length2; ++i)
MaxLen[0][i] = 0;
for (int i = 1; i <= length1; ++i)
{
for (int j = 1; j <= length2; ++j)
{
if (s1[i-1] == s2[j-1]){
MaxLen[i][j] = MaxLen[i-1][j - 1] + 1;
}
else
{
MaxLen[i][j] = max(MaxLen[i - 1][j], MaxLen[i][j - 1]);
}
}
}
return MaxLen[length1][length2];
}
int main(){
string s;
while (cin >> s){
int length = s.size();
if (length == 1){
cout << 1 << endl;
continue;
}
//利用迴文串的特點
string s2 = s;
reverse(s2.begin(),s2.end());
int max_length = maxLen(s, s2);
cout << length - max_length << endl;
}
return 0;
}