最长回文子串
dp
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
int maxLen = 1;
boolean[][] dp = new boolean[len][len];
String res = new String("");
for (int i=0; i<len; i++) {
for (int j=0;j<len-i;j++) {
if (i==0) {
dp[j][j+i] = true;
res = s.substring(j, j+1);
}
else if (i==1) {
if (s.charAt(j) == s.charAt(j+i)) {
dp[j][j+1] = true;
res = s.substring(j, j+2);
}
else {
dp[j][j+1] = false;
}
} else {
dp[j][j+i] = dp[j+1][j+i-1] && (s.charAt(j) == s.charAt(j+i));
res = (dp[j][j+i]) ? s.substring(j, j+i+1) : res;
}
}
}
return res;
}
}
马拉车算法
https://www.jianshu.com/p/392172762e55
每个字符都从自己向左右扩展,后面的字符可以根据条件,借助已经访问过的字符,减少扩展次数,将时间复杂度降到O(n)。
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() <= 1)
return s;
String s_temp = "#";
for (char c : s.toCharArray()) {
s_temp += c;
s_temp += '#';
}
int rignthEdge = -1;
int midIndex = -1;
int maxLen = -1;
int initIndex = -1;
int[] r = new int[s_temp.length()];
for (int i=0;i<s_temp.length();i++) {
if (rignthEdge > i)
r[i] = Math.min(r[2*midIndex - i], rignthEdge - i);
else
r[i] = 1;
while (i - r[i] >= 0 && i + r[i] <= s_temp.length()-1 &&s_temp.charAt(i - r[i]) == s_temp.charAt(i + r[i])) {
r[i]++;
}
if (i + r[i] > rignthEdge) {
midIndex = i;
rignthEdge = i+r[i];
}
if (2 * r[i] - 1 > maxLen) {
maxLen = 2*r[i]-1;
initIndex = i-r[i]+1;
}
}
String res = "";
for (int i=initIndex; i<initIndex+maxLen; i++) {
if (s_temp.charAt(i) != '#')
res += s_temp.charAt(i);
}
return res;
}
}