给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
1.中心扩散法
//中心扩散法
func longestPalindrome(s string) string {
if s == `` || len(s) < 2 {
return s
}
start, end := 0, 0
for i := 0; i < len(s); i++ {
left1, right1 := expandAroundCenter(s, i, i) //奇数
left2, right2 := expandAroundCenter(s, i, i+1) //偶数
if right1-left1 > end-start {
start, end = left1, right1
}
if right2-left2 > end-start {
start, end = left2, right2
}
}
return s[start : end+1]
}
func expandAroundCenter(s string, left, right int) (int, int) {
for ; left >= 0 && right < len(s) && s[left] == s[right]; left, right = left-1, right+1 {
}
return left + 1, right - 1
}
func main() {
s := `babad`
m := longestPalindrome(s)
fmt.Println(m)
}
2.动态规划
状态:dp[i][j]表示子串s[i...j]是否为回文子串
状态转移方程为:dp[i][j] = (s[i] == s[j])&& dp[i+1][j-1]
边界条件:j - i < 3 即:s[i...j]长度为2或3时,就不用再检查子串是否回文了
初始化:单个字符串一定是回文子串,dp[i][j] = true
输出:在得到一个状态的值为true的时候,记录起始位置和长度,填表完成后再截取
示例:

对角线为单个字符,肯定是true,左右边界确定下来,只需要填表格上半部分,0-1为ba所以是false,0-2为bab为true,依次类推
func longestPalindrome(s string) string {
n := len(s)
ans := ""
dp := make([][]int, n)
for i := 0; i < n; i++ {
dp[i] = make([]int, n)
}
for l := 0; l < n; l++ {
for i := 0; i+l < n; i++ {
j := i + l
if l == 0 {
dp[i][j] = 1
} else if l == 1 {
if s[i] == s[j] {
dp[i][j] = 1
}
} else {
if s[i] == s[j] {
dp[i][j] = dp[i+1][j-1]
}
}
if dp[i][j] > 0 && l+1 > len(ans) {
ans = s[i : i+l+1]
}
}
}
return ans
}
字符串中最长回文子串的求解方法

博客围绕在字符串中找最长回文子串展开,给出示例。介绍了两种求解方法,一是中心扩散法,二是动态规划法,阐述了动态规划的状态、状态转移方程、边界条件、初始化及输出方式,并给出示例说明填表过程。
897

被折叠的 条评论
为什么被折叠?



