问题描述
回文串是指这个字符串无论从左读还是从右读,所读的顺序是一样的;简而言之,回文串是左右对称的。现在,对于一个给定的母串
abcdedcb
可以找出子串a, ded,cdedc, bcdecdb等均是回文串;显然,bcdecdb是其中最长的那一个。但是该如何找出最长的回文子串呢?
问题解法
最容易想到的依然是穷举法,穷举所有子串,找出是回文串的子串,统计出最长的那一个。
动态规划
有母串s,我们用c[i,j] = 1表示子串s[i..j]为回文子串,那么就有递推式
c[i,j]={c[i+1,j−1]0if s[i]=s[j]if s[i]≠s[j]
递推式表示在s[i] =s[j]情况下,如果s[i+1..j-1]是回文子串,则s[i..j]也是回文子串;如果s[i+1..j-1]不是回文子串,则s[i..j]也不是回文子串。
初始状态:
· c[i][i]= 1
· c[i][i+1]= 1 if s[i] == s[i+1]
上述式子表示单个字符、两个字符均是回文串。
int longestPald(char *str) {
int len = strlen(str);
int c[maxLen][maxLen];
int i,j;
int longest = 1;
assert(str != NULL);
if(len == 1) {
return 1;
}
//initialization
for(i = 0; i < len; i++) {
c[i][i] = 1;
if(str[i] == str[i+1])
c[i][i+1] = 1;
}
for(i = 0; i < len; i++) {
for(j =i+2; j <= len; j++) {
if(str[i]== str[j]) {
c[i][j] = c[i+1][j-1];
//find longest palindrome substring
if(c[i][j]) {
int n = j - i + 1;
if(longest < n)
longest = n;
}
} else {
c[i][j] = 0;
}
}
}
return longest;
}
· 时间复杂度:O(n2).
· 空间复杂度:O(n2).