输入:“babad”
输出:“bab”或者“aba”
class Solution {
public String longestPalindrome(String s) {
int start = 0, end = 0;
for(int i = 0; i < s.length(); i++){
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i+1);
int len = Math.max(len1, len2);
if(len > end - start){
start = i - (len - 1)/2;
end = i + len/2;
}
}
return s.substring(start, end+1);
}
public static int expandAroundCenter(String s, int start, int end){
int L = start, R = end;
while(L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)){
L--;
R++;
}
return R - L - 1;
}
}
思路:对于n长的字符串他可以分割的点为2n - 1。因为如果是奇数位子串,则它的分割点为中间的字符,如果是偶数位子串,则
它的分割点为中间点。所以expandAroundCenter(s, i, i)就是奇数位子串的测试,从中心点逐渐向两边延伸
而expandAroundCenter(s, i, i+1)就是偶数位子串的测试。
string longestPalindromeDP(string s) {
int n = s.length();
int longestBegin = 0;
int maxLen = 1;
bool table[1000][1000] = {false};
for (int i = 0; i < n; i++) {
table[i][i] = true;
}
for (int i = 0; i < n-1; i++) {
if (s[i] == s[i+1]) {
table[i][i+1] = true;
longestBegin = i;
maxLen = 2;
}
}
for (int len = 3; len <= n; len++) {
for (int i = 0; i < n-len+1; i++) {
int j = i+len-1;
if (s[i] == s[j] && table[i+1][j-1]) {
table[i][j] = true;
longestBegin = i;
maxLen = len;
}
}
}
return s.substr(longestBegin, maxLen+longestBegin);
}
思路:使用P(i, j)表示从i到j的字符串是否为回文串,如果是则P(i, j) = 1, 否则为P(i, j) = 0。
基本条件P(i, i) = 1 P(i, i+1) = (s(i) == s(i+1))
因此得出推断 P(i, j) = (P(i+1, j - 1) and s(i) == s(j))
以上是最大只能为两个长度,所以我们应该考虑大于2的情况, 从3直至子串的长度,考虑的起始点为字符串的起始点,依次向后类推,判断是否符合回文串。