5. 最长回文子串

75 阅读1分钟

题目:
给你一个字符串 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
}