最长回文子串与最长回文子序列

最长回文子串

https://leetcode.com/problems/longest-palindromic-substring/

题目1:求最长回文子串

在这里插入图片描述

参考答案:

class Solution {
public:
    string longestPalindrome(string s) {
        int size=s.size();
        //处理特例
        if(size==0)return "";
        if(size==1)return s;
        
        //二维vector的初始化
        vector<vector<int>> dp(size,vector<int>(size,0));  
        for(int i=0;i<size;i++){
            dp[i][i]=1;
        }
        
        int start=0,maxLen=1;
        for(int len=2;len<=size;len++){//遍历所有可能的长度
            for(int i=0;i<size&&i-1+len<size;i++){//遍历所有可能的起点
                if(s[i]==s[i-1+len]){ //相等才需要继续判断,不等的话保留为0,即非回文串
                    //长度为2时没有内部子串需要判断了,直接判断为1
                    dp[i][i-1+len]=len==2?1:dp[i+1][i-2+len]; 
                    if(dp[i][i-1+len]&&len>maxLen){
                        maxLen=len;
                        start=i;
                    }
                }
            }
        }
        return s.substr(start,maxLen);
    }
};

题目2:求回文子串数量

在这里插入图片描述

参考答案:

class Solution {
public:
    int countSubstrings(string s) {
        int len=s.size();
        if(len<=1)return len;
        vector<vector<bool>> dp(len,vector<bool>(len,false));
        //bool dp[len][len];
        // 初始化len=1的状态并设置对应的结果,此处由于有len个长度为1的回文子串,故nums=len
        for(int i=0;i<len;i++)dp[i][i]=true;
        int nums=len;
        // 状态转移求出len>1的状态
        for(int n=2;n<=len;n++){
            for(int t=0;t<len && t+n-1<len;t++){
                int e=t+n-1;
                if(n==2){
                    dp[t][e]=s[t]==s[e];
                }else{
                    dp[t][e]=s[t]==s[e]?dp[t+1][e-1]:false;
                }
                if(dp[t][e])nums++;
            } 
        }
        return nums;
    }
};

最长回文子序列

https://leetcode.com/problems/longest-palindromic-subsequence/

在这里插入图片描述

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        int n = s.size();
        vector<vector<int>> dp(n+1,vector<int>(n));
        for(int i=0;i<n;i++) dp[1][i]=1;
        for(int i=2;i<=n;i++){ //length
            for(int j=0;j<n-i+1;j++) {//start index 
                dp[i][j] = s[j]==s[i+j-1]?2+dp[i-2][j+1]:max(dp[i-1][j],dp[i-1][j+1]);
            }
        }
        return dp[n][0]; 
    }
};

对比

忽略两个题目对于返回结果的不同要求(前者返回最长的结果,后者返回最长的结果对应的长度即可)。

dp数组的定义的区别:

最长回文子串:dp[i][j]表示的是string s中从ij的子串(用python语法就是s[i:j+1])是否为回文子串。

最长回文子序列:dp[i][j]表示的是长度为i起点为j子串(即s[j:j+i-1])的最长回文子序列的长度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值