516. 最长回文子序列 力扣(中等) 区间dp,不会做

516. 最长回文子序列

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

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

 

示例 1:

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

 

题解:https://leetcode-cn.com/problems/longest-palindromic-subsequence/solution/gong-shui-san-xie-qu-jian-dp-qiu-jie-zui-h2ya/

https://leetcode-cn.com/problems/longest-palindromic-subsequence/solution/dai-ma-sui-xiang-lu-dai-ni-xue-tou-dpzi-dv83q/

 

代码:

class Solution {
public:
    int longestPalindromeSubseq(string s) {
    // dp[i][j]:表示第i个字符到第j个字符之间,最长的回文子序列长度
    int dp[1005][1005];
    int l=s.length();
    memset(dp,0,sizeof(dp));
    for(int i=0;i<l;i++) dp[i][i]=1;
    for(int i=l-1;i>=0;i--)   // for(int i=0;i<l;i++)  因为看递推公式,需要借助下层结果,所以反着循环
      for(int j=i+1;j<l;j++)
      {
             if(i+1==j)
             {
                 if(s[i]==s[j]) dp[i][j]=2;
                     else dp[i][j]=1;
                continue;
             } 
            if (s[i]==s[j]) {dp[i][j]=dp[i+1][j-1]+2; continue;}
            if (s[i]!=s[j]) {dp[i][j]=max(dp[i+1][j],dp[i][j-1]); continue;}
      }
      return dp[0][l-1];
    }
};

 写法二:以长度为循环

class Solution {
public:
    int longestPalindromeSubseq(string s) {
    // dp[i][j]:表示第i个字符到第j个字符之间,最长的回文子序列长度
    int dp[1005][1005];
    int l=s.length();
    memset(dp,0,sizeof(dp));
 
      for(int len=1;len<=l;len++)
          for(int i=0;i+len-1<l;i++)
          {
              int j=i+len-1;
              if(len==1) {dp[i][j]=1; continue;}
          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]);
          }
      
     return dp[0][l-1];
    }
};

 

posted on 2021-08-12 20:47  Yxter  阅读(59)  评论(0编辑  收藏  举报

导航