【题目1】
给定一个字符串str,如果可以在str的任意位置添加字符,请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果。
【举例】
str="ABA"。str本身就是回文串,不需要添加字符,所以返回"ABA".
str="AB"。可以在'A'之前添加'B',使str整体都是回文串,故可以返回“BAB”。也可以在'B'之后添加'A',使str整体都是回文串,故也可以返回"ABA"。总之,只要添加的字符数最少,只返回其中一种结果即可。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int getParlindrome1(string s, string& res) {
if (s.size() == 0) return 0;
int len = s.size();
//Plan1
// vector<vector<int> >dp(len+1, vector<int>(len+1, 0));
//for (int i = len-1;i >=0;--i) {
// for (int j = i+1;j < len;++j) {
// if (s[i] == s[j]) {
// dp[i][j] = dp[i + 1][j - 1];
// }
// else {
// dp[i][j] = min(dp[i + 1][j], dp[i][j - 1]) + 1;
// }
// }
//}
//Plan2
vector<vector<int> >dp(len, vector<int>(len, 0));
for (int j = 1;j < len;++j) {
dp[j - 1][j] = s[j-1] == s[j] ? 0 : 1;
for (int i = j - 2;i > -1;--i) {
if (s[i] == s[j]) {
dp[i][j] = dp[i + 1][j-1];
}
else {
dp[i][j] = min(dp[i+1][j],dp[i][j-1]) + 1;
}
}
}
int addnumber = dp[0][len - 1];
int total = addnumber + len;
string tmp(total,'x');
int s_lhs = 0;
int s_rhs = len - 1;
int tmp_lhs = 0;
int tmp_rhs = total - 1;
while (s_lhs <= s_rhs) {
if (s[s_lhs] == s[s_rhs]) {
tmp[tmp_lhs++] = s[s_lhs++];
tmp[tmp_rhs--] = s[s_rhs--];
}
else if (dp[s_lhs][s_rhs] == dp[s_lhs][s_rhs -1] + 1) {
tmp[tmp_lhs++] = s[s_rhs];
tmp[tmp_rhs--] = s[s_rhs--];
}
else {
tmp[tmp_rhs--] = s[s_lhs];
tmp[tmp_lhs++] = s[s_lhs++];
}
}
res = tmp;
return addnumber;
}
int main() {
string s = "A1BC22DE1F";
string res = "";
cout << getParlindrome1(s,res) << endl;
cout << res << endl;
return 0;
}
【题目2】
给定一个字符串str,再给定str的最长回文子序列字符串strlps, 请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果。进阶问题比原问题多了一个参数,请做到时间复杂度比原问题的实现低。
【举例】
str=“A1B21C",strlps="121",返回“AC1B2B1CA”或者“CA1B2B1AC”,总之,只要是添加的字符数最少,只返回其中一种结果即可。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
void set(string& tmp,string& str,int& tmp_lhs,int& tmp_rhs,int lhs_st,int lhs_end,int rhs_st,int rhs_end ) {
for (int i = lhs_st;i < lhs_end;++i) {
tmp[tmp_lhs++] = str[i];
tmp[tmp_rhs--] = str[i];
}
for (int i = rhs_st;i > rhs_end;--i) {
tmp[tmp_lhs++] = str[i];
tmp[tmp_rhs--] = str[i];
}
}
int getParlindrome2(string str,string lps, string& res) {
if (str.size() == 0) return 0;
int str_len = str.size();
int lps_len = lps.size();
int total = 2 * str_len - lps_len;
string store(total,'-');
int str_lhs = 0;
int str_rhs = str_len - 1;
int lps_lhs = 0;
int lps_rhs = lps_len - 1;
int tmp_lhs = 0;
int tmp_rhs = total - 1;
while (lps_lhs<=lps_rhs) {
int lhs_st = str_lhs;
int rhs_st = str_rhs;
while (str[str_lhs] != lps[lps_lhs]) {
++str_lhs;
}
while (str[str_rhs] != lps[lps_rhs]) {
--str_rhs;
}
set(store,str,tmp_lhs,tmp_rhs,lhs_st,str_lhs,rhs_st,str_rhs);
store[tmp_lhs++] = str[str_lhs++];
store[tmp_rhs--] = str[str_rhs--];
++lps_lhs;
--lps_rhs;
}
res = store;
return total - str_len;
}
int main() {
string str = "A1BC22DE1F";
string strlps = "1221";
string res = "";
cout << getParlindrome2(str, strlps,res) << endl;
cout << res << endl;
return 0;
}
具体思路可参考《程序员代码面试指南》一书。