最长回文子串

  回文字符串,指一个字符串,从左到右和从右到左是完全一样的。判断一个字符串是否是回文,最简单的方式字符串头尾字符一一比较:

 1 bool IsPalindromes(const char *pstr, int n)
 2 {
 3     int i=0, j=n-1;
 4     while(i<j && pstr[i++]==pstr[j--])
 5         ;
 6     if (i>=j)     //i==j时,说明pstr长度为奇数,i>j时,说明长度为偶数
 7         return true;
 8 
 9     return false;
10 }

  也可以用递归来处理,更加简洁:

1 bool IsPalindromes_R(const char *pstr, int n)
2 {
3     if(n==0 || n==1)    //n==1说明pstr长度为奇数,n==0则长度为偶数
4         return true;
5     return pstr[0] == pstr[n-1] && 
6         IsPalindromes_R(pstr+1, n-2);
7 }

  理解了回文的概念,那么来看看如何求出最长回文子串。最容易想到的就是暴力破解,求出每一个子串,之后判断是不是回文,找到最长的那个,这样的时间复杂度太高O(n^3)。换一种思路,回文子串都是以中间的某个字符作为中心,然后向两边伸展,这样处理时间复杂度为O(n^2)。代码如下:

 1 void LongestPalindrome(const char *pstr, int n)
 2 {
 3     if(pstr == NULL || n<0)
 4         return;
 5 
 6     int i, j, k;
 7     int maxlen = 0;
 8     int start = 0;
 9     for(i=0; i!=n; i++)
10     {
11         j=i-1, k=i+1;    //这里表示如"aba"这样的相邻字符串
12         while(j>=0 && k<n && pstr[j]==pstr[k])    //回文为奇数情况
13         {
14             cout<<"odd:"<<pstr[j]<<" "<<pstr[k]<<endl;
15             if(k-j+1 > maxlen)
16             {
17                 maxlen = k-j+1;
18                 start = j;
19             }
20             j++;
21             k--;
22         }
23 
24         j=i-1, k=i;    //这里表示如"aa"这样的相邻字符串
25         while (j>=0 && k<n && pstr[j]==pstr[k])    //回文为偶数情况
26         {
27             cout<<"even:"<<pstr[j]<<" "<<pstr[k]<<endl;
28             if(k-j+1 > maxlen)
29             {
30                 maxlen = k-j+1;
31                 start = j;
32             }
33             j--;
34             k++;
35         }
36     }
37     cout<<"maxlen = "<<maxlen<<", start = "<<start<<endl;
38     char *pSubStr = new char[maxlen+1];
39     memset(pSubStr, 0x0, sizeof(char)*(maxlen+1));
40     strncpy_s(pSubStr, maxlen+1, pstr+start, maxlen);
41     cout<<"LongestPalindrome is: "<<pSubStr<<endl;
42     delete[] pSubStr;
43 
44     return;
45 }
原文地址:https://www.cnblogs.com/Tour/p/4062026.html