题目链接
思路
- "abcdcba"中"abcdcba"是回文子串;"bcdcb"也是回文子串
- 初始化一个end和start
- 动态规划:初始化一个boolean[][] dp;dp[i][j]表示字符串第i到j是否回文
- 单个字符默认回文
- 如果dp[i][j]回文,那么dp[i+1][j-1]也一定回文
- 采用i降序j升序嵌套遍历来保证判断dp[i][j]时,已经判断dp[i+1][j-1]
- 循环过程中,碰到回文将dp[i][j]置为true,标记为回文
- 当j-i>end-start时,将j和i分别赋值给end和start
- 最后将字符串下标start到end返回
- 注意:当出现j-i<3时,dp[i+1][j-1]是没有判断过的
java
public String longestPalindrome(String s) {
int len = s.length();
if (len < 2) {
return s;
}
boolean[][] dp = new boolean[len][len];
int start = 0;
int end = 0;
for (int i = len - 2; i >= 0; i--) {
dp[i][i] = true;
for (int j = i + 1; j < len; j++) {
if (s.charAt(i) == s.charAt(j) && (dp[i + 1][j - 1] || j - i < 3)) {
dp[i][j] = true;
if (end - start < j - i) {
start = i;
end = j;
}
}
}
}
return s.substring(start, end + 1);
}
go
func longestPalindrome(s string) string {
length := len(s)
if length < 2 {
return s
}
dp := make([][]bool, length)
for i := range dp {
dp[i] = make([]bool, length)
dp[i][i] = true
}
start, end := 0, 0
for i := length - 2; i >= 0; i-- {
for j := i + 1; j < length; j++ {
if s[i] == s[j] && (dp[i+1][j-1] || j-i < 3) {
dp[i][j] = true
if j-i > end-start {
start, end = i, j
}
}
}
}
return s[start : end+1]
}