516. 最长回文子序列
题目描述:
给你一个字符串 s
,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
解题思路:
算法思路:
1.
状态表⽰:
关于「单个字符串」问题中的「回⽂⼦序列」,或者「回⽂⼦串」,我们的状态表⽰研究的对象⼀
般都是选取原字符串中的⼀段区域
[i, j]
内部的情况。这⾥我们继续选取字符串中的⼀段区域
来研究:
dp[i][j]
表⽰:s 字符串
[i, j]
区间内的所有的⼦序列中,最⻓的回⽂⼦序列的⻓度。
2.
状态转移⽅程:
关于「回⽂⼦序列」和「回⽂⼦串」的分析⽅式,⼀般都是⽐较固定的,都是选择这段区域的「左
右端点」的字符情况来分析。因为如果⼀个序列是回⽂串的话,「去掉⾸尾两个元素之后依旧是回
⽂串」,「⾸尾加上两个相同的元素之后也依旧是回⽂串」。因为,根据「⾸尾元素」的不同,可
以分为下⾯两种情况:
i.
当⾸尾两个元素「相同」的时候,也就是
s[i] == s[j]
:那么
[i, j]
区间上的最
⻓回⽂⼦序列,应该是
[i + 1, j - 1]
区间内的那个最⻓回⽂⼦序列⾸尾填上
s[i]
和
s[j]
,此时
dp[i][j] = dp[i + 1][j - 1] + 2
ii.
当⾸尾两个元素不「相同」的时候,也就是
s[i] != s[j]
:此时这两个元素就不能同
时添加在⼀个回⽂串的左右,那么我们就应该让
s[i]
单独加在⼀个序列的左边,或者
让
s[j]
单独放在⼀个序列的右边,看看这两种情况下的最⼤值:
•
单独加⼊
s[i]