第十一周作业:
516. Longest Palindromic Subsequence
解题思路:
516. Longest Palindromic Subsequence
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.
Example 1:
Input:
"bbbab"Output:
4One possible longest palindromic subsequence is "bbbb".
Example 2:
Input:
"cbbd"Output:
2One possible longest palindromic subsequence is "bb".
思路:典型的动态规划题目,参考LCS的递推公式:

i和j表示从第i到j个字符串的最长长度。
将矩阵画出会比较直观:
以"bbbab"为例:行代表i,列代表j
1 2 3 3 4不难看出,初始状态是将上三角全部初始化为1:
0 1 2 2 3
0 0 1 1 3
0 0 0 1 1
0 0 0 0 1
1 0 0 0 0然后我们要逐渐来填充这个矩阵,保证右上角的是最终结果,即dp[0][length-1]。
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
所以我们从最后一行开始填写这个矩阵。即i从length-1到0,然后j从i+1到length,即这样一个顺序:
先考虑一个简单的情况,当s[i]!=s[j]时,这个时候也就是说,dp[i][j]一定包含于dp[i+1][j]或dp[i][j-1]中。因为i是降序,j是升序,那么降序的上一步就是i+1,升序的上一步就是j-1。在矩阵中就是当前元素的左边或者下边。
第二种情况,当s[i]==s[j],这个时候说明,当前位置的子串会对整体长度的贡献产生影响,那么这个贡献是多少呢,比如说b******b这样一个子串,当i=0,j=length-1时,i和j分别在两个b的位置,那么dp[i][j]的值一定是dp[i+1][j-1]的值再加上头和尾这两个b的值,也就是dp[i][j]=dp[i+1][j-1]+2。
这就是两种递推式。
代码如下:
class Solution {
public:
int longestPalindromeSubseq(string s) {
vector<vector<int>> dp(s.length(), vector<int>(s.length()));
for (int i = 0; i < s.length(); i++)
dp[i][i] = 1;
for (int i = s.length() - 1; i >= 0; i--) {
for (int j = i + 1; j < s.length(); 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[0][s.length() - 1];
}
};