最长回文子序列(LeetCode-516)

简介: 最长回文子序列(LeetCode-516)

最长回文子序列(LeetCode-516)


题目

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。


子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。


示例 1:

输入:s = "bbbab"
输出:4
解释:一个可能的最长回文子序列为 "bbbb" 。


示例 2:

输入:s = "cbbd"
输出:2
解释:一个可能的最长回文子序列为 "bb" 。


提示:


1 <= s.length <= 1000

s 仅由小写英文字母组成


思路

五部曲


dp[i][j] 含义


在区间范围为 [ i , j ]  (注意左右都是闭区间)内的最长的回文子序列的长度

递推公式


当 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 ] 时,d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] + 2


数组初始化


当下标 i = j  时,即一个字符的回文子序列长度应该为一

遍历顺序

要注意看当前元素依靠谁的状态获取,看到递推公式,就知道肯定对于 i 的遍历肯定要倒序。


代码展示

class Solution
{
public:
    int longestPalindromeSubseq(string s)
    {
        int n = s.size();
        if (n == 1)
        {
            return 1;
        }
        vector<vector<int>> dp(n, vector<int>(n));
        for (int i = n - 2; i >= 0; i--)
        {
            dp[i][i] = 1;
            for (int j = i + 1; j < n; 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][n - 1];
    }
};
目录
相关文章
|
7月前
|
Java
leetcode-491:递增子序列
leetcode-491:递增子序列
46 0
|
7月前
leetcode-1332:删除回文子序列
leetcode-1332:删除回文子序列
53 0
|
2月前
acwing 895 最长上升子序列1
acwing 895 最长上升子序列1
30 3
|
2月前
acwing 1016 最大上升子序列和
acwing 1016 最大上升子序列和
24 0
|
7月前
|
算法 测试技术 C#
【单调队列】LeetCode1425:带限制的子序列和
【单调队列】LeetCode1425:带限制的子序列和
【单调队列】LeetCode1425:带限制的子序列和
|
7月前
|
JavaScript
代码随想录 Day48 动态规划16 T647 回文子串 T516最长回文子序列
代码随想录 Day48 动态规划16 T647 回文子串 T516最长回文子序列
45 0
|
7月前
|
存储
leetcode-940:不同的子序列 II
leetcode-940:不同的子序列 II
36 0
|
7月前
leetcode-516:最长回文子序列
leetcode-516:最长回文子序列
37 0
|
7月前
leetcode-115:不同的子序列
leetcode-115:不同的子序列
34 0
|
7月前
|
测试技术
leetcode-152:乘积最大子数组
leetcode-152:乘积最大子数组
62 0