最长回文子序列
给定一个字符串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
}