# leetcode#5最长回文数C++

leetcode#5最长回文数C++

一.思路一:中心扩散

对每一个字符,检测它与它旁边的数是否为回文数,如果是,那么再扩展它 的长度检查,分奇偶情况讨论,得到以该字符为中心最长的回文数。在遍历过程中用max[2]储存该目前最长的回文数位置和长度。这样算法时间复杂度为O(n^2)。

1.1代码实现

1.1.1# 新工具

string s;
s.substr(int i,int j);
用于截取string,返回s[i]开始j个字符。
string+=s[i];
int max(int a,int b)
返回a,b中大的一个

1.1.2# 不甘放弃
class Solution {
public:
    string longestPalindrome(string s) {
        int len=s.size();
        if(len==0||len==1)
            return s;
        int start=0;//记录最大回文子串起始位置
        int end=0;//记录最大回文子串终止位置
        int mlen=0;//记录以s【i】为中心最大回文子串的长度
        for(int i=0;i<len;i++)
        {
            int len1=expendaroundcenter(s,i,i);//一个元素为中心
            int len2=expendaroundcenter(s,i,i+1);//两个元素为中心
            mlen=max(max(len1,len2),mlen);//记录以i为中心的最大回文数
            if(mlen>end-start+1)//记录最大的回文数
            {
                start=i-(mlen-1)/2;
                end=i+mlen/2;
            }
            /*if(i>len/2&&mlen/2>len-i)
            break;(精简步骤edition2)*/ 
        }
        return s.substr(start,mlen);
        //该函数的意思是获取从start开始长度为mlen长度的字符串
    }
private:
    int expendaroundcenter(string &s,int left,int right)
    //!!!!这里&s,大幅提升效率!!!!!
    //计算以left和right为中心的回文串长度
    {
        int L=left;
        int R=right;
        while(L>=0 && R<s.length() && s[R]==s[L])//防止越界我
        {
            L--;
            R++;
        }
        return R-L-1;
    }
};
```/*
改编自chenlele
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-c-by-gpe3dbjds1/
来源:力扣(LeetCode)*/

执行用时:16 ms, 在所有 C++ 提交中击败了94.83%的用户
内存消耗:6.9 MB, 在所有 C++ 提交中击败了99.68%的用户

思考

可以根据已有最长回文串长度mlen与i的位置,进一步缩小程序。
edition 2
在这里插入图片描述
可以看见用时缩短了一倍,但内存增加了0.1mb

1.2简化:Manacher

给字符串插#

字符+###总长
偶数+奇数奇数
“abcd”“#a#b#c#d#”
奇数+偶数奇数
“abc”“#a#b#c#”
1.2.1实现方法

用一个辅助string存储新字符串,得到辅助最长回文串以[i]为中心,扩散了mlen步,长2*mlen+1。
映射到原字符串以i/2为中心扩散了mlen/2步。
那么这个字符串覆盖了2 *(mlen/2)个间隔

0123
abcd
辅助01234567

输出:
start = (i - mlen) / 2;
return s.substr(start, mlen);

1.2.2代码实现

   int centerSpread(string &s, int center) {
       int len = s.size();
       int i = center - 1;
       int j = center + 1;
       int step = 0;
       while (i >= 0 && j < len && s[i] == s[j]) {
           i--;
           j++;
           step++;
       }
       return step;
   }

public:


   string longestPalindrome(string &s) {
       int size = s.size();
       if (size < 2) {
           return s;
       }

       string str = "#";
       for (int i = 0; i < s.size(); ++i) {
           str += s[i];
           str += "#";
       }
       int sSize = 2 * size + 1;
       int maxLen = 1;

       int start = 0;
       for (int i = 0; i < sSize; i++) {
           int curLen = centerSpread(str, i);
           if (curLen > maxLen) {
               maxLen = curLen;
               start = (i - maxLen) / 2;
           }
       }
       return s.substr(start, maxLen);
   }
};

作者:liweiwei1419
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/
来源:力扣(LeetCode)

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值