回文指一个顺着读和反过来读都一样的字符串,比如 madam、我爱我。回文判断是一类典型的问题,尤其是与字符串结合后呈现出多姿多彩。
一、回文判断
如何判断一个字串是否是回文,最直接的方法显然是将字符串逆转,存入另外一个字符串,然后比较原字符串和逆转后的字符串是否一样,一样就是回文,这个方法的时空复杂度都是 O(n)。
很容易想到只要从两头开始同时向中间扫描字串,如果直到相遇,两端的字符都一样,那么这个字串就是一个回文。我们只需要维护头部和尾部两个扫描指针即可。这样的算法,时间复杂度为O(n),空间复杂度为O(1)。已经达到了最佳的性能。代码如下:
int isHuiWen(char *buf, int len)
{
inti, j;
assert(buf);
i= 0; j = len-1;
while(i< j)
{
if(buf[i++]!= buf[j--])
{
return0;
}
}
return1;
}
或者从中间开始向两边扫描,考虑到字符串的长度有奇偶数的区分,所以,中间元素也有两种情况,代码如下:
int isHuiWen2(char * buf,int len)
{
int i, j;
assert(buf);
if(len% 2 != 0) //长度为奇数的情况
{
i= len/2;
j= len/2;
}
else //长度为偶数的情况
{
j= len/2;
i= j-1;
}
while(i>=0&& j<len)
{
if(buf[i--]!= buf[j++])
{
return0;
}
}
return1;
}
二:最长回文子串
如果需要查找一个字符串中的最长回文字串,那么如何高效的进行判断呢?可以利用上一节中的第二种思路,从一个字符开始,向两边扩展,看看最多能到多长,使其保持为回文。这也就是为什么在上一节里面要提出isHuiWen2的原因。
具体而言,可以枚举中心位置,然后再在该位置上用扩展法,记录并更新得到的最长的回文长度,即为所求。扩展法需要考虑两种情况,举例来说就是:”abc”和”abbc”的情况。代码如下:
for(k= 0; k < len; k++)
{
i= k;
j= k;
huiwenlen= 0;
while(i>= 0 && j < len)
{
if(buf[i]== buf[j])
{
huiwenlen= j - i + 1;
}
else
{
break;
}
i--;
j++;
}
if(maxhuiwenlen< huiwenlen)
{
index1= i+1;
index2= j-1;
maxhuiwenlen= huiwenlen;
}
i= k;
j= k+1;
huiwenlen= 0;
while(i>= 0 && j < len)
{
if(buf[i]== buf[j])
{
huiwenlen= j - i + 1;
}
else
{
break;
}
i--;
j++;
}
if(maxhuiwenlen< huiwenlen)
{
index1= i+1;
index2= j-1;
maxhuiwenlen= huiwenlen;
}
}
printf("themax huiwen len is %d\n", maxhuiwenlen);
printf("thelongest huiwen is: ");
for(i= index1; i <= index2; i++)
{
printf("%c",buf[i]);
}
printf("\n");
(http://blog.csdn.net/v_july_v/article/details/6712171)