前言
最长回文数序列
二维DP数组解决
对于一些字符串问题,比如求一串字符中最长的回文串,或者是一些回文串的变种问题,我们一般可以使用一个二维的DP数组来保存计算的结果,从而减少计算量,下面我用两个例题来解释
例题1
例题2
516. Longest Palindromic Subsequence
给定一个字符串s,找出s中最长的回文子序列的长度。
子序列是一个序列,可以通过删除部分或不删除元素而从另一个序列派生,而不改变其余元素的顺序。
我们可以将一个字符串的任意字串用一个二维DP数组来表示,比如s[2,4]可以表示为DP[2][4]
所以我们这个问题可以用DP[2][4]表示字符串s的[2,4]字串中最长的回文串的长度
所以这个问题的state transition 方程为:
{
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
+
1
]
+
2
s
[
i
]
=
s
[
j
]
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
]
[
j
+
1
]
)
s
[
i
]
≠
s
[
j
]
\begin{cases} dp[i][j] = dp[i-1][j+1] + 2 & s[i] = s[j]\\ dp[i][j] = max(dp[i-1][j], \ dp[i][j+1]) & s[i] ≠s[j] \end{cases}
{dp[i][j]=dp[i−1][j+1]+2dp[i][j]=max(dp[i−1][j], dp[i][j+1])s[i]=s[j]s[i]=s[j]
Example 1:
Input: s = "bbbab"
Output: 4
Explanation: One possible longest palindromic subsequence is "bbbb".
Example 2:
Input: s = "cbbd"
Output: 2
Explanation: One possible longest palindromic subsequence is "bb".
class Solution {
public:
int longestPalindromeSubseq(string s) {
int lens = s.size();
vector<vector<int>> dp(lens, vector<int>(lens, 0));
for(int i=0; i<lens; i++){
dp[i][i] = 1;
for(int j=i-1; j>=0; j--){
if(s[i] == s[j]){
dp[i][j] = dp[i-1][j+1] + 2;
}else{
dp[i][j] = max(dp[i-1][j], dp[i][j+1]);
}
}
}
return dp[lens-1][0];
}
};



最长公共子序列
这种问题跟最长回文序列一样,要用一个二维DP数组来解题
对于两个子序列,用一个二层嵌套for循环来遍历,若s1[i] == s2[j],则我们的公共子序列长度可以加一
如果s[i] != s[j],则我们比较{s1[:i-1], s[:j]}和{s1[:i], s[:j-1]},也就是dp[i][j-1]和dp[i-1][j],选择较大的一个作为dp[i][j]的值
例题1
最长递增子序列
此类问题用一个一维DP数组即可解决,DP数组s[:i]表示序列前i个元素的最长递增子序列的长度
例题1
最长扭动子序列
这题我也不咋会写。。。。。丢脸了
1685



被折叠的 条评论
为什么被折叠?



