算法设计作业11

来源:互联网 发布:javascript 15天写好的 编辑:程序博客网 时间:2024/06/05 20:24

第十一周作业:

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:
4
One possible longest palindromic subsequence is "bbbb".

Example 2:
Input:

"cbbd"
Output:
2
One possible longest palindromic subsequence is "bb".


思路:典型的动态规划题目,参考LCS的递推公式:

i和j表示从第i到j个字符串的最长长度。
将矩阵画出会比较直观:
以"bbbab"为例:行代表i,列代表j
 1 2 3 3 4 
0 1 2 2 3
0 0 1 1 3
0 0 0 1 1
0 0 0 0 1
不难看出,初始状态是将上三角全部初始化为1:
1 0 0 0 0 
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
然后我们要逐渐来填充这个矩阵,保证右上角的是最终结果,即dp[0][length-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;elsedp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);}}return dp[0][s.length() - 1];}};


0 0