题意:
给定一个字符串,判断其最长回文子串。即这个子串从左边读和从右边都是相同的。一开始想到用dp,因为对于一个回文串来说,它的子串还是回文串,当然边界条件是回文串长度小于等于二(a、aa)。代码有些繁琐还可以继续优化。
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if (len <= 1)
return s;
String result;
if(s.charAt(0) == s.charAt(1))
result = s.substring(0,2);
else
result = s.substring(0,1);
boolean[][] dp = new boolean[len][len];
for(int i = 0;i<len;i++)
dp[i][i] = true;
int max = 1;
for (int i = 2; i < len; i++) {
for(int j = 0;j<i;j++) {
if(s.charAt(i) == s.charAt(j) && ( i-j <=2 || dp[j+1][i-1] )) {
dp[j][i] = true;
if(max < i - j + 1) {
max = i - j + 1;
result = s.substring(j, i+1);
}
}
}
}
return result;
}
}
第二种解法:中心扩散法。
- 回文子串长度为奇数。例如:ababa这样子的。
- 回文子串长度为偶数。例如:abba。
因此,需要比较两种情况,双指针i和j分别向两边扩散,即i- - , j++。长度为j - i + 1,大于最长则更新。
代码如下:
class Solution {
String result = "";
int max = 0;
public String longestPalindrome(String s) {
if (s.length() <= 1)
return s;
for (int i = 0; i < s.length(); i++) {
maxPa(s, i, i);
maxPa(s, i, i + 1);
}
return result;
}
private void maxPa(String s, int i, int j) {
int left = i;
int right = j;
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
if(right-left+1 > max) {
max = right - left+1;
result = s.substring(left, right+1);
}
left--;
right++;
}
}
}