添加最少字符串使字符串整体都是回文串-C++版

【题目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;
}
具体思路可参考《程序员代码面试指南》一书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder567

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值