题意
用最少的替换字母次数,将输入的字符串变成变成回文字符(如果相同的替换次数有多组解,输出字典序最小的一种),字母的位置可以任意改变(不计入次数)
思路
定义两个数组,一个数组记录每个字母出现的次数,另一个记录出现出现奇数次的字母,出现偶数次的不用改变,出现奇数次的从两边往中间遍历,使出现奇数次的字母 (小的加一 大的减一)变为偶数次 。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+11;
int main()
{
char s[maxn];
int h[26],v[30]={0};
cin>>s;
int n=strlen(s);
int m=0;
memset(h,0,sizeof(h));
for(int i=0;i<n;i++)
{
h[s[i]-'a']++;
}
for(int i=0;i<26;i++)
{
if(h[i]%2!=0)
v[m++]=i;
}
int k=0;
for(int i=0,j=m-1;i<j;i++,j--) //将出现奇数次的字母改为偶数次 取两个奇数次字母中小的那一个
{
h[v[i]]++;
h[v[j]]--;
}
if(n%2!=0) //当输入字符串长度为奇数时 最后就会有一个字母出现奇数次取(出现奇数次字母中)中间那个
s[n/2]=v[m/2]+'a';
for(int i=0,j=n-1;i<j;i++,j--)
{
while(h[k]<=1) // 会出现一次h[k]=1 的情况 且 k=v[m/2]
k++;
if(h[k]>=2)
{
s[i]=k+'a';
s[j]=k+'a';
h[k]-=2;
}
}
cout<<s<<endl;
return 0;
}
借鉴了别人的代码才写出来的 。。。