无意中看到一个网友提的问题:关于c语言回文串的问题,一时无聊,随手写了一个
问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入
5
mamad
样例输出
3
据说这个是蓝桥杯的题目,一听就是学生时代的竞赛。作为一个中老年码农,上学那会儿电脑没有那么普及,也没有这样的比赛。专门去搜了一下什么是蓝桥杯,呵呵,好像很专业的样子啊。赞助商里面,做外包的居多啊,青年朋友们擦亮眼睛啊。
思路
只能两辆互换,这个有点麻烦。两头一起向中间凑。下面是两个栗子。
字符串 | 交换序号 |
---|---|
ma m ad | 0 |
maa m d | 1 |
maad m | 2 |
mad a m | 3 |
字符串 | 交换序号 |
---|---|
m m aad | 0 |
ma m ad | 1 |
maa m d | 2 |
maad m | 3 |
mad a m | 4 |
参考代码
以下实现的空间复杂度为O(n),时间复杂度为O(n^2)。
#include <stdio.h>
#include <string.h>
#define MAX_INPUT_LEN 8000
int main()
{
int alpha[26]={0}; // statistical bucket
int nLen = 0; // length of the input string
int nScanLen = 0;
int swap_num = 0; // count of swap
int odd_char = 0; // number of chars with odd appearance
int even_char = 0; // number of chars with even appearance
char str[MAX_INPUT_LEN]={0};
char* pcur = str;
int i,j,k;
scanf("%d", &nLen);
scanf("%s", str);
nScanLen = strlen(str);
if (nScanLen != nLen) return 0;
if (nLen == 0) return 0;
i=0;
do{
alpha[str[i++] -'a']++;
}while(str[i]!=0);
#ifdef _DEBUG
printf("\n");
#endif
for(i=0; i<26;i++)
{
#ifdef _DEBUG
if(alpha[i]!=0)printf("DBG: [%c] = %d\n",i+'a', alpha[i]);
#endif
odd_char += alpha[i]%2;
even_char += alpha[i] && !(alpha[i]%2);
}
#ifdef _DEBUG
printf("DBG: odd_char = %d, even_char = %d\n",odd_char, even_char);
#endif
if( odd_char == (nLen%2 ? 1 : 0))
{
#ifdef _DEBUG
printf("DBG: swap[%4d], str = %s\n", swap_num, str);
#endif
i = 0;
j = nLen-1-i;
// from both ends to the middle
while(i<=j)
{
#ifdef _DEBUG
printf("DBG: i=%d, j=%d\n",i,j);
#endif
k = j;
// from right to left , find the first position equal to the left current char
while(k>i)
{
if (str[k]!=str[i]) k--;
else break;
}
// swap the found char to its target position
while(k<j)
{
str[k] ^= str[k+1];
str[k+1] ^= str[k];
str[k] ^= str[k+1];
k++;
swap_num++;
#ifdef _DEBUG
printf("DBG: swap[%4d], str = %s\n", swap_num, str);
#endif
}
i++;
j = nLen-1-i;
}
#ifdef _DEBUG
printf("\nswap = ");
#endif
printf("%d\n",swap_num);
}
else
{
printf("\nImpossible\n");
}
return 0;
}