先暴力
package mainimport ("fmt"
)func longestPalindrome(s string) string {bytes := []byte(s)var count intvar res string = string(bytes[0])for i := 0; i < len(s); i++ {var temp string = string(bytes[i])for j := i + 1; j < len(s); j++ {temp = temp + string(bytes[j])if JudgePalindrome(temp) && count < len(temp) {res = tempcount = len(temp)}}}return res
}func JudgePalindrome(s string) bool {bytes := []byte(s)var res []bytefor i := len(s) - 1; i > -1; i-- {res = append(res, bytes[i])}str := string(res)if str == s {return true} else if str != s {return false}return false
}func main() {/*给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。*/s := "ccc"fmt.Println(longestPalindrome(s))
}
发现虽然给的一些例子答案都对,但是提交的时候超时了,时间复杂度达到了O(n^3),看看能不能优化。
我尝试着优化一下判断回文的函数,不用整个颠倒后来,只颠倒一半,如下:
func JudgePalindrome(s string) bool {length := len(s)if length%2 == 0 {slice1 := s[:length/2]slice2 := s[length/2:]var slice3 []bytefor i := len(slice2) - 1; i > -1; i-- {slice3 = append(slice3, slice2[i])}if string(slice1) == string(slice3) {return true} else {return false}} else if length%2 == 1 {slice1 := s[:length/2]slice2 := s[length/2+1:]var slice3 []bytefor i := len(slice2) - 1; i > -1; i-- {slice3 = append(slice3, slice2[i])}if string(slice1) == string(slice3) {return true} else {return false}}return false
}
还是超时,因为没有从数量级上降低时间复杂度,依然是O(n^3),看来得从根本上优化。
看了一下 leecode 给的官方题解,采用了中心扩展算法将时间复杂度降到了 O(n^2),主要的思想就是如果中心的子串是回文串,那么就尝试着向两边扩散,算法用 debug 跑一遍很好懂,代码如下:
func longestPalindrome(s string) string {if s == "" {return s}start, end := 0, 0for i := 0; i < len(s); i++ {left1, right1 := ExpandPalindrome(s, i, i)left2, right2 := ExpandPalindrome(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 ExpandPalindrome(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
}
接下来是动态规划的代码题解,同样也是将时间复杂度降到了O(n^2)。官方题解有视频讲解
func longestPalindrome(s string) string {n := len(s)dp := make([][]bool, n)for i,_ := range dp {dp[i] = make([]bool, n)}ans := ""for l:=0; l<n; l++ { // l为本次循环遍历的子串长度for i:=0; i+l<n; i++ {j := i+lif l == 0 {dp[i][j] = true} else if l == 1 {dp[i][j] = (s[i] == s[j])} else {dp[i][j] = (s[i] == s[j] && dp[i+1][j-1])}if dp[i][j] && l+1 > len(ans) {ans = s[i:j+1]}}}return ans
}作者:Bonheur
链接:https://leetcode.cn/problems/longest-palindromic-substring/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。