LeetCode: Longest Palindromic Substring

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: "babad"

Output: "bab"

Note: “aba” is also a valid answer.
Example:

Input: "cbbd"

Output: "bb"

最长回文串
思路:Manacher算法


这里写图片描述

很明显最大的P[i]值减1即为最长的回文字符串长度。所以问题来了,怎么计算P这个数组是接下来的重点。
Manacher算法增加两个辅助变量mid和maxid,mid代表的是最长回文串的中心的位置,maxid是最长回文串的边界即mid+P[mid]。
Manacher算法有个很重要的结论:IF maxid>i, P[i]>=min(P[2*mid-i],maxid-i]
这个结论怎理解呢?
如下图,我们设置位置j为i关于mid的对称点,j=2*mid-i
这里写图片描述

当maxid-i>P[i]时,以位置i为中心的最长回文串和以j为中心的最长回文串是相同的。解释一下,因为以mid为中心的最长回文串的边界是maxid,则在maxid对称点和maxid之间的字符串是回文的,所以,以位置i为中心的最长回文串和以j为中心的最长回文串是相同的。即P[i]=P[j]。
当maxid-i<=P[i]时,直观上就是以位置i为中心的最长回文串的边界超过了maxid。此时,只能在超出maxid边界继续匹配。
当maxid<=i时,直接令P[i]=1,继续匹配。
这里写图片描述

困了,代码稍晚贴出来,晚安。

关于代码我说一下,用的例子是leetcode的,在sublime上调试结果是wyyw,但在leetcode平台上是eiee,该题目在leetcode平台一共有94个test,通过了93个,第94个见鬼了,两个平台不一样。如果你发现为什么两个平台不一样,私信我。
日了狗了。。。截图如下:

这里写图片描述
这里写图片描述

#include <iostream>
#include "string"
#include "algorithm"
#include "vector"
using namespace std;

class Solution {
public:
    string longestPalindrome(string s) {
        string str="";
        int length=s.size();
        if(length<=1)
            return s;
        for(int i=0;i<length;i++)
            {
                str+="#";
                str+=s[i];
            }
        str+="#";
        return manacher(str,s);

    }
    string manacher(string str,string s);
};
string Solution::manacher(string str,string s)
{
    int mid=0,maxid=0;
    int length=str.size();
    vector<int> P(length,0);
    for(int i=0;i<length;i++)
    {
        if(maxid>i)
        {
            P[i]=min(P[2*mid-1],maxid-i);
        }
        else{
            P[i]=1;
        }
        while(i-P[i]>=0&&i+P[i]<=length&&str[i+P[i]]==str[i-P[i]])
        {
            P[i]++;
        }
        if(maxid<P[i]+i)
        {
            maxid=i+P[i];
            mid=i;
        }
    }
    int max=0,index=0;
    for(int i=0;i<length;i++)
    {
        if(max<=P[i])
        {
            index=i;
            max=P[i];
        }
    }
    string subStr="";
    if(index%2==1)
    {
        subStr=s.substr(index/2-(max-1)/2,max-1);
    }
    else{
        subStr=s.substr(index/2-max/2,max-1);
    }
    return subStr;
}

int main()
{
    string str="apqjpwedlhmvvpexxnntxheeynxmgzwxhnhfdvziuxnuusymklgcacndoyhqkoahnkyaikohwkmnuphipftmzmihvmoetskioeypwjujvvusaxynzxxdugnebsisrtgeujkqkgwjuplijhluumqcdurovyjsbowmnqndejwkihzbbdyxjunkduyqeihektaknbmkzgnnmgywylulxwyywrvieqfenjeljofkqqqisdjsbfkvqgahxwkfkcucvrbbpyhwkfztjdboavtfynrudneieelwlcezqsuhmllcsadcnoyemsfdlrijoyj";
    int len=str.size();
    Solution sol;
    string str1=sol.longestPalindrome(str);
    for(int i=0;i<str1.length();i++)
    {
        cout<<str1[i];
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值