Lever's Castle

5. 最长回文子串

November 03, 2019

https://leetcode-cn.com/problems/longest-palindromic-substring/

使用语言:Golang

解:

func longestPalindrome(s string) string {
    if len(s) <= 1 {
        return s
    }
    
    var max string
    for i := range s[:len(s) - 1] {
        // 处理两边相等的情况
        str := findPalindrome(s, i, i)
        if len(str) > len(max) {
            max = str
        }
        // 处理相邻相等的情况
        str = findPalindrome(s, i, i+1)
        if len(str) > len(max) {
            max = str
        }
    }
    return max
}


func findPalindrome(s string, l, r int) string {
    for l >= 0 && r <= len(s) - 1 && s[l] == s[r] {
        l--
        r++
    }
    return string(s[(l+1):r])
}

首先,我们需要明确什么是回文串。回文串可以简单的理解成把一个字符串从中间分开分成左右两部分,左边的字符串反过来排列即为右边的字符串,可以认为从中间分开后,两边是对称的。

那我们就可以定义出回文串的特性了:假设回文串 s 长度为 n,则有 s[i] == s[n-1-i] (i < n)。

再回头看问题,我们要求解的是最长的回文子串,分解一下这个问题,我们要求的是找到这个字符串中的所有回文串,然后选出最长的来。

那么怎么找到所有的回文串呢?

回文串的中心是关键。找到中心后向两边扩散,直到不满足条件的左值和右值为止,这中间的字符串便是回文串了。这就是代码中 findPalindrome 在做的事情。

那么,我们便假设字符串中的每个字符都有可能是中心,然后以此为准向两边扩散找到回文串。对于回文串来说,可能是个偶数长度,也可能是个奇数长度。偶数长度,两边直接对称,奇数长度则以中心字母为基准两边对称。而在原始字符串中的每个字符,可能是奇数长度回文串的中心字母,也可能是偶数长度回文串的中心左侧的字母。因此便有了 findPalindrome(s,i,i)findPalindrome(s, i, i+1)

综上,我们在遍历所有回文子串的过程中,找到了最长回文子串。


Lever

痕迹
没有过去,就没法认定现在的自己