516. 最长回文子序列-M
label: dp,回文,字符串
给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。
示例 1:
输入:
“bbbab”
输出:
4
一个可能的最长回文子序列为 “bbbb”。
示例 2:
输入:
“cbbd”
输出:
2
一个可能的最长回文子序列为 “bb”。
分析:
典型的dp,dp[i][j]表示s{i,j}的最长回文字串,接下来我们看s[i-1]和s[j+1]是否相等,若不等则要扩展数据,这时要看dp[i+1][j]和dp[i][j-1]谁大,然后更新到dp[i][j]上;因为s[i]!=s[j],但可能s[i+1]==s[j]或者s[i]==s[j-1],之前一直忽略这里,导致错误很多。
package main
import "fmt"
/*
执行用时 :36 ms, 在所有 Go 提交中击败了86.67%的用户
内存消耗 :18 MB, 在所有 Go 提交中击败了100.00%的用户
*/
func longestPalindromeSubseq(s string) int {
dp:=make([][]int,len(s))
for i:=0;i<len(s);i++{
dp[i]=make([]int,len(s))
dp[i][i]=1
if i>0&&s[i]==s[i-1]{
dp[i-1][i]=2
}
}
size:=len(s)
for i:=size-1;i>=0;i--{
for j:=i+1;j<size;j++{
if s[i]==s[j]{
if j==i+1{
dp[i][j]=2
}else{
dp[i][j]=dp[i+1][j-1]+2
}
}else{
if dp[i+1][j]>dp[i][j-1]{
dp[i][j]=dp[i+1][j]
}else{
dp[i][j]=dp[i][j-1]
}
}
}
}
max:=0
for i:=0;i<size;i++{
if max<dp[i][size-1]{
max=dp[i][size-1]
}
}
return max
}
func main() {
tables:=[]string{
"bbbab",
"aaaa",
"cbbd",
"",
"abcabcabcabc",
}
for _,v:=range tables{
fmt.Println(longestPalindromeSubseq(v))
}
}