LeetCode 0516 Longest Palindromic Subsequence【DP,最长回文子序列】

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”.


题意

思路1

  • 定义一个二维的dp[i][j]来表示字符串第i个字符到第j个字符的长度,子问题也就是每个子回文字符串的长度。
  • 对于d[i][j],我们根据上题的分析依然可以看出, 当s[i]s[j]相等时,s[i+1...j-1]这个字符串加上2就是最长回文子序列; 当s[i]s[j]不相等时,就说明可能只有其中一个出现在s[i,j]的最长回文子序列中,我们只需要取s[i-1,j-1]加上s[i]或者s[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])
  • 从下往上,从左往右更新 dp 所有的值
  • 始化条件 很明显看出来的当只有一个字符的时候,最长回文子序列就是1,所以可以得到dp[i][j]=1(i=j) 接下来我们来看看 当i>j时,不符合题目要求,不存在子序列,所以直接初始化为0。 当`i时,每次计算表中对应的值就会根据前一个状态的值来计算。
  • dp[0][len - 1] 即表示起点为 0 终点为 n-1 的字符串的最大回文长度

代码1

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        int len = s.size();
        vector<vector<int>> dp(len, vector<int>(len));
        for(int i = 0; i < len; i++)
            dp[i][i] = 1;
        for(int i = len - 1; i >= 0; i--)
        {
            for(int j = i + 1; j < len; j++)
            {
                if(s[i] == s[j])  // 两个字符相等时,子字符串+2
                    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][len - 1];
    }
};
发布了166 篇原创文章 · 获赞 27 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/HdUIprince/article/details/105692621