【LeetCode】516. 最长回文子序列

180 阅读1分钟

最长回文子序列

给定一个字符串s,找到其中最长的回文子序列,并返回该序列的长度。可以假设s的最大长度为1000 。

示例1

输入:
"bbbab"
输出:
4

示例2

输入:
"cbbd"
输出:
2

思路

  • 题目中说“最大长度”,可思考动态规划来解决该问题。
  • 回文字符串是说首尾的字符相同。换句话说,我们将回文子序列看作是另一个字符串(将该字符串逆序输出)。求最长的回文子序列,就是说求两个字符串的最长公共子序列。
  • dp[i][j]表示:s1区间[0:i-1]和s2区间[0:j-1]的最长公共子序列。
  • 如果s1[i]==s2[j]时,则dp[i+1][j+1]=dp[i][j]+1
  • 如果s1[i]!=s2[j]时,则dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1])

解法

func longestPalindromeSubseq(s string) int {
    m:=len(s)
    s2:=""
    for i:=len(s)-1;i>=0;i--{ // 从后往前,获取逆序输出的序列
        s2+=string(s[i])
    }
    dp:=make([][]int,len(s)+1) // 定义二维动态数组
    for i:=0;i<len(s)+1;i++{
        dp[i]=make([]int,len(s)+1)
    }
    for i:=0;i<=m-1;i++{
        for j:=0;j<=m-1;j++{
            if s[i]==s2[j]{ // 如果两元素相等,则dp[i+1][j+1]=dp[i][j]+1
                dp[i+1][j+1]=dp[i][j]+1
            }else{ // 如果两元素不相等,则dp[i+1][j+1]为dp[i+1][j]和dp[i][j+1]的最小值
                dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]) 
            }
        }
    }
    return dp[m][m]
}
func max(a,b int)int{
    if a>b{
            return a
    }
    return b
}