Leetcode-5 最长回文子串

动态规划
1.确定DP数组以及下标含义
2.确定递推公式(状态转移方程)
3.初始化
4.注意遍历顺序(状态由较短回文串向较长回文串转移)即填表时参考的值不能还未计算——先计算dp[ i + 1 ][ j - 1 ]再计算dp[ i ][ j ]

class Solution {
public:
    string longestPalindrome(string s) {
        int n=s.size();
        //先考虑边界条件
        //初始值
        if(n==1) return s;
        if(n==2&&s[0]==s[1]) return s;

        int maxlen=0,begin=0;
        //确定DP数组,下标含义:表示区间范围内[i,j]子串是否是回文串
        vector<vector<int>> dp(n, vector<int>(n,1));
        //填表顺序非常关键
        //在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的
        //因此一定要注意动态规划的循环顺序
        for(int i=n-1;i>=0;i--){
            for(int j=i;j<n;j++){
                //判定规则,状态转移方程
                if(s[i]!=s[j]){
                    dp[i][j]=0;
                }else{
                    if(j-i<3){
                        dp[i][j]=1;
                    }else{
                        dp[i][j]=dp[i+1][j-1];
                    }
                }
                //更新,只需要记录起点和长度
                if(dp[i][j]&&j-i+1>maxlen){
                    maxlen=j-i+1;
                    begin=i;
                }
            }
        }
        return s.substr(begin,maxlen);
    }
};

中心扩散法

class Solution {
public:
    int maxLength=0;
    int start=0,end=0;
    
    string longestPalindrome(string s) {
        //中心扩散法
        int n=s.size();
        if(n==0||n==1)return s;

        //遍历每一个位置当作中心位
        for(int i=0;i<n;i++){
            expandCenter(s,i,i);//len_odd
            expandCenter(s,i,i+1);//len_even
        }
        return s.substr(start,maxLength);
    }

    //s输入的字符串 left起始左边界 right起始右边界 返回值 回文串长度
    int expandCenter(string s,int left,int right){
        //找到字符串可能的回文子串中心
        //奇数:具体字符
        //偶数:两个字符中间的空隙
        while (left >= 0 && right < s.size() && s[left] == s[right]){
            if (right - left + 1 > maxLength) {
                start = left;
                end = right;
                maxLength = right - left + 1;
            }
            left--;
            right++;
        }
        return maxLength;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值