题干
如题,请配合豆包 Marscode AI刷题 题序142 最小回文构造问题食用,此处不粘贴题目描述。减少客官滑鼠标的手指劳损
思路
这题本意是输入一个字符串,要用有限字符把它改为字典序相对最小的回文字符串,但是可能出题人也觉得这题的测试数据不好生成,于是加了个规定“测试数据保证答案存在”,也即,测试数据给的输入一定能在两次替换字符操作内被转化为回文串,该限定直接将本题砍为单纯的逻辑判断题。
我们只需设置两个指向需要修改地方的下标,分几种情况讨论即可(长度为奇或偶——>有0到2个字符“破坏队形”),算法时间复杂度为O(n)(n为字符串长度),判断最坏情况要遍历n/2,改字符最坏情况要遍历n/2次。不废话了直接上代码
代码
#include <iostream>
#include <string>
#include <algorithm>
std::string solution(const std::string& s) {
if(len == 1) return "a";
std::string r = s;
int len = s.size();
int c1=-1, c2=-1;//由于最多只有两个字符要改,此处定义两个变量记录下标
//奇数长字符串有个“中心字符”,比较特殊,故奇偶分开考虑
if(len%2 == 0){
for(int i=0;i<len/2;i++)
if(s[i]!=s[len-1-i]){
if(c1 < 0) c1 = i;
else c2 = i;
}
if(c1>=0 && c2 == -1)
r[c1] = r[len - c1 - 1] = 'a';
else if(c1 >= 0 && c2 >= 0){
char t1=std::min(r[c1],r[len-c1-1]);
char t2=std::min(r[c2],r[len-c2-1]);
r[c1] = r[len - c1 - 1] = t1;
r[c2] = r[len - c2 - 1] = t2;
}
else
for(int i=0;i<len/2;i++)
if(r[i]!='a'){
r[i] = r[len - i -1] = 'a';
break;
}
}
else{
for(int i=0;i<len/2;i++)
if(s[i]!=s[len-1-i]){
if(c1 < 0) c1 = i;
else c2 = i;
}
if(c1>=0 && c2 == -1){
char t=std::min(r[c1],r[len-c1-1]);
if(t == 'a'){
r[len/2] = 'a';
r[c1] = r[len - c1 - 1] = t;
}
else
r[c1] = r[len - c1 - 1] = 'a';
}
else if(c1 >= 0 && c2 >= 0){
char t1=std::min(r[c1],r[len-c1-1]);
char t2=std::min(r[c2],r[len-c2-1]);
r[c1] = r[len - c1 - 1] = t1;
r[c2] = r[len - c2 - 1] = t2;
}
else
for(int i=0;i<=len/2;i++)
if(r[i]!='a'){
r[i] = r[len - i -1] = 'a';
break;
}
}
return r;
}
int main() {
std::cout << (solution("acca") == "aaaa") << std::endl;
std::cout << (solution("racecar") == "aacecaa") << std::endl;
std::cout << (solution("fecdef") == "feaaef") << std::endl;
return 0;
}
感想
本题丢给豆包或者Marscode AI居然都写不出来,看来灵活思考能力与逻辑水平这块离人类目前还有些距离。