编程学习笔记(LeetCode-516. 最长回文子序列)

<516>最长回文子序列

  • 问题重述:
    设有以字符串 \(s\) ,找出其最长回文子序列,并且返回该序列的长度。


    子序列: 不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
    回文: 即是正读和反读都一样的字符串(例如:aba,abba,bbbb等)。


    注: 单个字符也被认为是一个回文串;

示例1:

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

示例2:

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

限定:
\(1 \leqslant s.length \leqslant 1000\)
\(s\) 仅由小写英文字母组成

解析与求解(动态规划)

  • 对于一个子序列,若它是回文子序列,且长度大于 2 ,去其首位,其仍是一个回文子序列。
  • 若用 \(dp[i][j]\) 表示 \(s[i,j]\) 内最长的回文子串长度,且 \(n\) 为字符串的长度,那么:

\[\begin{cases} dp[i][j]>0,\qquad 0\leqslant i\leqslant j<n;\\ dp[i][j]=0,\qquad i,j\in (-\infty , 0)\cup [n, \infty);\\ \end{cases} \]

  • 由于任何长度为1的子序列都是回文子序列,那么:

\[dp[i][j]=1,\qquad i=j\ and\ 0\leqslant i\leqslant j<n; \]

  • \(i<j\) 时,需要分别考虑 \(s[i]=s[j]\)\(s[i]\neq s[j]\) 的情况。
    \(s[i]=s[j]\) 时:

    \[dp[i][j]=dp[i+1][j-1]+2 \]

    \(s[i] \neq s[j]\) 时:

    \[dp[i][j]=max(dp[i+1][j],\ dp[i][j-1]) \]

dp计算顺序:

  • 我们想要的结果最终会落在 \(dp[0][n-1]\) 处。
  • 状态转移方程都是从长度较短的子序列向长度较长的子序列转移。
    那么dp的计算顺序为:
    从矩阵的右下角开始计算,每行从\((dp[i][j],\ i=j)\) 开始计算。

C++代码实现:

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        //创建动态规划数组dp
        vector<vector<int> > dp = vector<vector<int> >(s.size(), vector<int>(s.size(), 0));
        for(int i = s.size() - 1; i >= 0; i--){
            for(int j = i; j < s.size(); j++){
                if(i > j){continue;}        //0 <= i <= j <= n
                //长度为1的字符为回文串
                else if(i == j){dp[i][j] = 1;}
                //提示: 当是s[i]=s[j]且i和j相邻的时候,
                //      那么i+1=j,j-1=i,dp[i+1][j-1]即为dp[i][j]的对称点。
                //      由于dp[i][j]的对称点值为0,所以长度恰好是0+2
                else if(s[i] == s[j]){dp[i][j] = dp[i+1][j-1]+2;}
                //当首尾字符不相等的时候,返回去掉当前的首或者当前的尾后的最长回文子序列
                else if(s[i] != s[j]){dp[i][j] = max(dp[i][j-1], dp[i+1][j]);}
            }
        }
        //返回最终结果
        return dp[0][s.size()-1];
    }
};

时空复杂度:

  • 时间复杂度: \(O(n^2),\ n\)为字符串 \(s\) 的长度。
  • 空间复杂度: \(O(n^2),\ n\)为字符串 \(s\) 的长度。



备注: 摘录自LeetCode官方题目解析。

posted on 2021-08-15 15:56  丶LittleBoy  阅读(89)  评论(0)    收藏  举报