我的代码
这题就一直修修补补,注释已经写不动了,还好最后性能还行。
#include <stdio.h>
#include <stdlib.h>
void func(char *s, int n) {
int alphabet[26] = {0}, max = 0, loc1 = 0, loc2, flag = 0;
for (int i = 0; i < n; ++i)
alphabet[s[i] - 97]++;
for (int i = 1; i < 26; ++i)
if (alphabet[i] > alphabet[max])
max = i; //找到数量最多的字符
if (alphabet[max] > n / 2 + n % 2) {
printf("INVALID");
return; //最多的字符超出极限
}
while (alphabet[loc1] == 0)
++loc1;
loc2 = loc1 + 1;
while (alphabet[loc2] == 0)
++loc2; //找到第一第二小的字符
for (int i = 0; i + 2 <= n; i += 2) { //一一取代原字符串
if (alphabet[max] == (n - i) / 2 + (n - flag) % 2) {
s[i + 1 - (n - flag) % 2] = max + 97;
if (--alphabet[max] == 0 && i != n - 2) {
for (int i = 0; i < 26; ++i)
if (alphabet[i] > alphabet[max])
max = i;
if (alphabet[max] > (n - i) / 2 + (n - i) % 2) {
printf("INVALID");
return;
}
}
while (alphabet[loc2] == 0)
++loc2;
if (alphabet[loc1] == 0) {
loc1 = loc2;
while (alphabet[++loc2] == 0);
}
if (max != loc1) {
s[i + (n - flag) % 2] = loc1 + 97;
--alphabet[loc1];
} else {
s[i + (n - flag) % 2] = loc2 + 97;
--alphabet[loc2];
}
continue;
}
s[i] = loc1 + 97;
alphabet[loc1]--;
s[i + 1] = loc2 + 97;
alphabet[loc2]--;
if (loc1 == max || loc2 == max) {
for (int i = 0; i < 26; ++i)
if (alphabet[i] > alphabet[max])
max = i;
}
if (alphabet[loc1] == 0 && alphabet[loc2] == 0) {
while (alphabet[++loc2] == 0);
loc1 = loc2;
while (alphabet[++loc2] == 0);
} else {
while (alphabet[loc2] == 0)
++loc2;
if (alphabet[loc1] == 0) {
loc1 = loc2;
while (alphabet[++loc2] == 0);
++i;
++flag;
s[i + 1] = loc2 + 97;
alphabet[loc2]--;
}
}
}
if ((n - flag) % 2) {
while (alphabet[loc1] == 0) {
++loc1;
}
s[n - 1] = loc1 + 97;
}
printf("%s", s);
}
int main() {
int n;
scanf("%d", &n);
char *s = (char *) malloc(sizeof(char) * n);
scanf("%s", s);
func(s, n);
//printf("%d",'{');
return 0;
}