Given a string S, find the longest palindromic substring in S. You may assume that the maximum length ofS is 1000, and there exists one unique longest palindromic substring.
思路:Palindrome分奇数和偶数个,像aba, abba。这里的方法叫做中间生长法,从中间开始,i,j向两边扩展,如果相同继续,否则return,这样来算,O(n^2)的复杂度。
2N-1个center。为什么有2n-1个中心,是因为,每个字符可以做中心,这个没什么问题,那么abba的中心就是两个b之间的空字符串,这样当你生长的时候,要以bb为起点开始两边生长,这样的话,每次都以空字符串生长,这样是n-1个。
注意最后需要用s.substring(start+1,end),因为循环最后已经对start和end进行了--和++的操作。
找中心点的操作就是:扫两遍,分别以 (i,i) (i,i+1)为左右指针,开始扫描,找对称的string,然后更新。
class Solution {
public String longestPalindrome(String s) {
if(s == null || s.length() == 0) {
return s;
}
String longest = "";
for(int i = 0; i < s.length(); i++) {
String oddstr = getPalindrome(s, i, i);
String evenstr = getPalindrome(s, i, i + 1);
if(oddstr.length() > longest.length()) {
longest = oddstr;
}
if(evenstr.length() > longest.length()) {
longest = evenstr;
}
}
return longest;
}
private String getPalindrome(String s, int i, int j) {
while(0 <= i && j < s.length()) {
if(s.charAt(i) == s.charAt(j)) {
i--;
j++;
} else {
break;
}
}
return s.substring(i + 1, j);
}
}
此题同时可以用dp来做。我觉得此题的突破点就在于dp的矩阵表示的物理意义是什么。这点抓住了,其实这题就出来了。
dp[i][j] 表示的物理意义是:string s里面i到j之间的string是否是palindrome. 那么很自然的会推导出递推关系:
if s(i) != s(j) 直接 dp[i][j] = false;
if s(i) == s(j) :
if( j-i<=2) dp[i][j] = true; // aba, 这个是容易犯错的点。 j-i = 2的情况一定要考虑进去;
else dp[i][j] = dp[i+1][j-1] 代表i,j指针向中间移动;
因为计算dp[i][j] 需要用到下一层的dp[i+1][j-1],所以for循环的时候,要从下开始算,也就是从后面开始计算;
class Solution {
public String longestPalindrome(String s) {
if(s == null || s.length() == 0) {
return s;
}
int n = s.length();
boolean[][] f = new boolean[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
f[i][i] = true;
}
}
char[] schar = s.toCharArray();
String longest = "";
int start = 0; int end = 0;
int maxlen = 0;
for(int i = n - 1; i >= 0; i--) {
for(int j = i + 1; j < n; j++) {
if(schar[i] != schar[j]) {
f[i][j] = false;
continue;
} else {
// schar[i] == schar[j];
if(j - i <= 2 || f[i + 1][j - 1]) {
f[i][j] = true;
if(j - i + 1 > maxlen) {
maxlen = j - i + 1;
start = i;
end = j;
}
}
}
}
}
return s.substring(start, end + 1);
}
}