发现自己原来掌握的一下算法,都忘掉了,啊啊啊
------------------------------------------------------------------------------------------------------
Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S.
You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
【题意】:给你一个字符串,求最长回文字符子串。
【心路历程】:这题一开始我就照着O(n)的方法想,一开始是想扫描一遍字符串,然后递增的处理奇数回文串和偶数回文串的情况。
但是发现对于既可以是奇数回文串也可以是偶数回文串的情况处理不了,比如“aaaa”,“aaa”。于是感觉到自己想歪了。
这题有个O(n)的方法,但是没看懂。。。
一般的方法是O(n*2),有两个大的思路:
一个是枚举回文串中心的位置,然后不断地向两边递增。直到不满足回文串的要求。
一个是动态规划的思想,dp[i][j]表示从i到j字符串是不是回文串,有两个值True ,False。动态转移方程为:
dp[i][j] = ( dp[i+1][j-1] && s[i] == s[j] ).
其实还可以将字符串反转一下,然后求最长连续公共子串。(其实这个是以前我处理最长回文子串常用的方法,但是这次做题已经忘得一干二净了)
动态转移方程为: dp[i][j] = max( dp[i-1][j-1] + (s[i] == s[j]), dp[i-1][j], dp[i][j-1] )
-------------------------------------------------------------------------------------------------------------------------------------------
代码如下:
首先是枚举回文串中心的位置的代码:
1 struct node { 2 int l; 3 int r; 4 }; 5 struct node f(char * s,int l,int r,int len) { 6 struct node a; 7 while(l >= 0 && l < len && r >= 0 && r < len && s[l] == s[r]) { 8 l--; 9 r++; 10 } 11 a.l = l + 1; 12 a.r = r - 1; 13 return a; 14 } 15 16 char* longestPalindrome(char* s) { 17 int i,len,l,max = 0; 18 len = strlen(s); 19 char * ans = (char *)malloc(1000*sizeof(char)); 20 struct node p; 21 int maxr,maxl; 22 for(i = 0; i < len; i++) { 23 p = f(s,i,i,len); 24 l = (p.r - p.l + 1); 25 if(l > max) { 26 max = l; 27 maxr = p.r; 28 maxl = p.l; 29 } 30 if(i + 1 < len && s[i] == s[i + 1]) { 31 p = f(s,i,i+1,len); 32 l = (p.r - p.l + 1); 33 if(l > max) { 34 max = l; 35 maxr = p.r; 36 maxl = p.l; 37 } 38 } 39 } 40 for(i = 0; i < maxr - maxl + 1; i++) { 41 ans[i] = s[maxl + i]; 42 } 43 ans[i] = ‘\0‘; 44 return ans; 45 }
然后是dp的代码:
1 char* longestPalindrome(char* s) { 2 int dp[1001][1001]; 3 int max = 1,start = 0; 4 char * ans = (char*)malloc(1000*sizeof(char)); 5 memset(dp,0,sizeof(dp)); 6 int len = strlen(s),i,j; 7 for(i = 0; i < len; i++) { 8 dp[i][i] = 1; 9 } 10 for(i = 0; i < len; i++) { 11 if(i + 1 < len && s[i] == s[i + 1]) { 12 dp[i][i+1] = 1; 13 if(2 > max) { 14 max = 2; 15 start = i; 16 } 17 } 18 } 19 for(i = 3; i <= len ;i++) { 20 for(j = 0; j + i <= len; j++) { 21 if(s[j] == s[j+i-1] && dp[j+1][i+j-2]) { 22 dp[j][j+i-1] = 1; 23 if(i > max) { 24 max = i ; 25 start = j; 26 } 27 } 28 } 29 } 30 for(i = 0; i < max; i++) { 31 ans[i] = s[start + i]; 32 } 33 ans[i] = ‘\0‘; 34 return ans; 35 }