小美的回文串 Problem Description
现在小美获得了一个字符串。小美想要使得这个字符串是回文串。 小美找到了你。你可以将字符串中至多两个位置改为任意小写英文字符′a′− ′z′。 你的任务是帮助小美在当前制约下,获得字典序最小的回文字符串,数据保证能在题目限制下形成回文字符串。
注:回文字符串:即一个字符串从前向后和从后向前是完全一致的字符串。例如字符串abcba,aaaa,acca都是回文字符串。字符c串abcd,acea都不是回文字符串。input
一行,一个字符串。字符串中仅由小写英文字符构成。 保证字符串不会是空字符串。 字符串长度介于[1,100000] 之间。
ouput
一行,一个在题目条件限制下所可以获得的字典序最小的回文字符串。
Sample Input 1
acca
Sample Output 1
aaaa
说明: 原来的字符串已经是回文字符串了。但它不是题目条件下可以取得的字典序最小的回文字符串。将第二个字符和第三个字符都改为a可以获得字典序最小的回文字符串。Sample Input 2
abcde
Sample Output 2
abcba
说明 将de改为ba可以获得字典序最小的回文字符串。
题目类型、难度、来源
- 类型:暴力
- 难度:简单
- 来源:美团校招-2023.3.18.10点-第三题-小美的回文串
总体思路:
- 暴力法。题目保证能最多改两个字符达成回文串。那么只有三种情况:
- 有两个字符对(对称位置的两个字符)不对称。这种情况下必须用掉两次修改的机会,即把字符对中字典序较大的值改为较小的那个字符值。例如字符对为a,e,就要将e改为a。
- 有一个字符对不对称。这种情况需要使用一次修改机会让字符串变为回文串,具体是把字符对中字典序较大的值改为较小的那个字符值。此时字符串已经回文了,再修改字符对会令字符串不再回文。为了不浪费修改机会,我们要看字符串长度是否是奇数,如果是奇数,就将中间的字符改为’a’。
- 输入的字符串本身就是对称的。这种情况最简单,只要从左到右遍历字符串,将第一个字符对都改成’a’。
AC代码
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
cin >> s;
int n = s.size();
int cnt = 0, p1 = -1, p2 = -1;
for (int i = n-1; i >= n/2; i--){
if (s[i] == s[n-1-i]) continue;
cnt++;
if (cnt == 1){
p1 = n-1-i;
}else if (cnt == 2){
p2 = n-1-i;
}
}
if (cnt == 2){
char c1 = min(s[p1], s[n-1-p1]);
char c2 = min(s[p2], s[n-1-p2]);
s[p1] = s[n-1-p1] = c1;
s[p2] = s[n-1-p2] = c2;
}else if (cnt == 1){
char c1 = min(s[p1], s[n-1-p1]);
s[p1] = s[n-1-p1] = 'a';
if (c1 == 'a' && n%2==1){
s[n/2] = 'a';
}
}else if (cnt == 0){
for (int i = 0; i < n; i++){
if (s[i] != 'a'){
s[i] = s[n-1-i] = 'a';
break;
}
}
}
cout << s;
return 0;
}
- 更多大厂真题可以看:2023实习、秋招互联网大厂技术岗算法真题-刷题(持续更新)