二维DP
首先确定dp[i][j]
含义:字符串s[i...j]
的最长回文子序列。
转移方程:如果知道dp[i+i][j-1]
能不能知道dp[i][j]
。
图中dp[i+1][j-1] = 1
,s[i] == s[j]
,由图可以看出dp[i][j] = 3
:aca。
那么可以得出当s[i] == s[j]
时,dp[i][j] = dp[i+1][j-1]
。
当s[i] != s[j]
时,那么i或j其中一个就不在s[i...j]
的最长回文子串中,分别求一下dp[i+1][j] dp[i][j-1]
大小就能知道谁不在了。
i == j的地方dp肯定为1,i > j的地方不合理所以遍历只需要遍历二维数组的上半部分。
func longestPalindromeSubseq(s string) int {
n := len(s)
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n)
}
for i := 0; i < n; i++ {
dp[i][i] = 1
}
for i := n - 1; i >= 0; i-- {
for j := i + 1; j < n; j++ {
if s[i] == s[j] {
dp[i][j] = dp[i+1][j-1] + 2
} else {
dp[i][j] = max(dp[i][j-1], dp[i+1][j])
}
}
}
return dp[0][n-1]
}
func max(i, j int) int {
if i > j {
return i
}
return j
}