最长回文子串

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

 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 }

你可能感兴趣的:(回文)