题目:
给你一个字符串 s,找到 s 中最长的回文子串。
解法:
动态规划,dp[i][j]表示,s(i:j)是否为回文子串,s(i:j)取决于s(i+1,j-1)
方法一: 动态规划
func longestPalindrome(s string) string {
n := len(s)
if n < 2 {
return s
}
dp := make([][]bool, n)
for i := 0; i < n; i ++ {
dp[i] = make([]bool, n)
dp[i][i] = true
}
begin := 0
maxLen := 1
for L := 2; L <= n; L ++ {
for i := 0; i < n; i ++ {
j := L + i - 1
if j >= n {
continue
}
if s[i] == s[j] {
if j - i + 1 <= 3 {
dp[i][j] = true
} else {
dp[i][j] = dp[i + 1][j - 1]
}
} else {
dp[i][j] = false
}
if dp[i][j] && j - i + 1 > maxLen {
begin = i
maxLen = j - i + 1
}
}
}
return s[begin:begin + maxLen]
}
方法二: 暴力法
func longestPalindrome(s string) string {
maxLegnth := 0
maxStr := ""
for i := 0; i < len(s); i ++ {
// aba
// j 要从0开始,单个字符
for j := 0; 0 <= i - j && i + j < len(s); j ++ {
if s[i - j] == s[i + j] {
if j * 2 + 1 > maxLegnth {
maxLegnth = j * 2 + 1
maxStr = s[i - j: i + j + 1]
}
} else {
break
}
}
// aa
for l, r := i, i + 1; 0 <= l && r < len(s); l, r = l - 1, r + 1 {
if s[l] == s[r] {
if r - l + 1 > maxLegnth {
maxLegnth = r - l + 1
maxStr = s[l:r + 1]
}
} else {
break
}
}
}
return maxStr
}
方法三: 中心扩散法
func longestPalindrome(s string) string {
maxLegnth := 0
maxStr := ""
for i := 0; i < len(s); i ++ {
left1, right1 := expand(s, i, i)
left2, right2 := expand(s, i, i + 1)
if right1 - left1 + 1 > maxLegnth {
maxLegnth = right1 - left1 + 1
maxStr = s[left1:right1 + 1]
}
if right2 - left2 + 1 > maxLegnth {
maxLegnth = right2 - left2 + 1
maxStr = s[left2:right2 + 1]
}
}
return maxStr
}
func expand(s string, l, r int) (int, int) {
for ; 0 <= l && r < len(s) && s[l] == s[r]; l, r = l - 1, r + 1 {}
return l + 1, r - 1
}