image.png

image.png

状态定义

dp[l,r]:字符串s从索引l到r的子串是否是回文串
true: s[l,r] 是回文串
false:s[l,r] 不是回文串

状态转移

dp[l][r] = dp[l+1][r-1] && s[l] == s[r]
s[l] == s[r]:说明当前中心可以继续扩张,进而有可能扩大回文串的长度
dp[l+1][r-1]:true
说明s[l,r]的子串s[l+1][r-1]也是回文串

边界处理

l - r <= 2:2表示aba类型;1表示aa类型;0表示a类型 这些只需要判断s[l]==s[r]就可以了
总结
dp[l][r] = s[l] == s[r] && ( r - l <= 2&&dp[l+1][r-1])

从头部开始遍历

  1. func longestPalindrome(s string) string {
  2. if len(s)<2 {
  3. return s
  4. }
  5. dp :=make([][]bool,len(s))
  6. for i:=range s{
  7. dp[i] = make([]bool,len(s))
  8. }
  9. result := string(s[0])
  10. for r:=0;r<len(s);r++{
  11. for l:=0;l<=r;l++{
  12. if s[l]==s[r]&&(r-l<=2||dp[l+1][r-1]){
  13. dp[l][r]= true
  14. if len(s[l:r+1])>len(result){
  15. result =s[l:r+1]
  16. }
  17. }
  18. }
  19. }
  20. return result
  21. }

从尾部开始遍历

  1. package main
  2. import "fmt"
  3. // 动态规划
  4. func longestPalindrome(s string) string {
  5. dp :=make([][]bool,len(s))
  6. for i:=range s{
  7. dp[i] = make([]bool,len(s))
  8. }
  9. result := ""
  10. for i :=len(s)-1;i>=0;i-=1{
  11. for j:=i;j<len(s);j+=1{
  12. dp[i][j] = s[i]==s[j]&&(j-i<3||dp[i+1][j-1])
  13. if dp[i][j]&&j-i+1>len(result) {
  14. result = s[i:j+1]
  15. }
  16. }
  17. }
  18. return result
  19. }
  20. func main() {
  21. fmt.Println(longestPalindrome("babad"))
  22. }
  1. func longestPalindrome(s string) string {
  2. lenth := len(s)
  3. if lenth <= 1 {
  4. return s
  5. }
  6. dp := make([][]bool, lenth)
  7. start := 0
  8. max := 1
  9. for r := 0;r<lenth;r++ {
  10. dp[r] = make([]bool, lenth)
  11. for l:=0;l<r;l++ {
  12. dp[l][r]= s[l] == s[r] && (r -l <= 2 || dp[l+1][r-1])
  13. if dp[l][r] {
  14. curr := r-l+1
  15. if curr > max {
  16. max = curr
  17. start = l
  18. }
  19. }
  20. }
  21. }
  22. return s[start:start+max]
  23. }