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, and there exists one unique longest palindromic substring.


算法一:

最开始看到题目时,还是首先使用暴力法求解试水。首先,编写函数判断某个字符串是否是回文字符串。该函数做法为:将原字符串分割为长度相等的字符串s1和s2(若字符串长度为奇数,则忽略中间位置的字符,中间字符不影响字符串的回文性),接着,判断s1的第一位与s2的最后一位是否相同,s1的第二位与s2的倒数第二位是否相同,以此类推,直至s1的最后一位与s2的第一位。若其中有一位不同,则函数返回结果0,表示字符串不是回文字符串。否则,函数返回字符串的长度。

接着,对于一个给定的字符串,遍历该字符串的所有子字符串,用上述函数判断其是否为回文字符串,并实时更新当前最大长度的回文字符串。最终返回结果。

int PalindromeLen(string s)
{
    int len=s.length();
    bool is=true;
    if (len%2==0)
    {
        string str1=s.substr(0,len/2);
        string str2=s.substr(len/2,len/2);
        int i,j;
        for (i=0,j=str2.length()-1;i<str1.length();i++,j--)
        {
            if (str1[i]!=str2[j])
                is=false;
        }
        
        if (is)
            return s.length();
        else
            return 0;
    }
    
    else
    {
        string str1=s.substr(0,len/2);
        string str2=s.substr(len/2+1,len/2);
        int i,j;
        for (i=0,j=str2.length()-1;i<str1.length();i++,j--)
        {
            if (str1[i]!=str2[j])
                is=false;
        }
        
        if (is)
            return s.length();
        else
            return 0;
    }
}


string longestPalindrome(string s) {
    if (s.length()==1)
        return s;
    int maxLen=0;
    int l;
    string maxStr="";
    string str;
    for (int i=0;i<s.length();i++)
    {
        for (int j=i+1;j<s.length();j++)
        {
            str=s.substr(i,j-i+1);
            if (PalindromeLen(str)>maxLen)
            {
                maxLen=PalindromeLen(str);
                maxStr=str;
            }
        }
    }
    return maxStr;
}
提交后,果不其然,这种算法是超时的。遍历全部子字符串的复杂度为O(n^2),判断是否为回文字符串的复杂度为O(n),代码的时间复杂度为O(n^3)。很明显,需要另一种复杂度更低的算法。


算法二:

首先,为避免出现越界,当字符串长度为0时,返回空字符串,当字符串长度为1时,返回字符串本身。

假设要判断的字符串s为gabcdcbak。则算法步骤为:在字符串中的某一位i,判断s[i]与s[i+1]是否相等,若不相等,则i++,继续遍历字符串。如果相等,则用变量b记录子字符串开头,初始为b=i,用变量e记录子字符串结尾,初始为e=i+1。接着,判断s[b]与s[e]是否相等,若相等,则b--,e++,扩展子字符串,并继续判断s[b]与s[e]是否相等。当子字符串已经越界或者s[b]与s[e]不相等时,记录从位置b+1到位置e-1的回文子字符串,并更新当前最大长度的回文子字符串。该算法的复杂度为O(n^2)。

string longestPalindrome(string s)
{
    if (s.length()==0)
        return "";
    else if (s.length()==1)
        return s;
    else if (s.length()==2)
    {
        if (s[0]==s[1])
            return s;
        else
            return "";
    }
    
    string result;
    int b,e;
    for (int i=0;i<s.length();i++)
    {
        
        if (i>0&&s[i-1]==s[i+1])
        {
            b=i-1;
            e=i+1;
            while (b>=0&&e<s.length()&&s[b]==s[e])
            {
                b--;
                e++;
            }
            b++;
            e--;
            if (result.length()<e-b+1)
                result=s.substr(b,e-b+1);
        }
        
        if (s[i]==s[i+1])
        {
            b=i;
            e=i+1;
            while (b>=0&&e<s.length()&&s[b]==s[e])
            {
                b--;
                e++;
            }
            b++;
            e--;
            if (result.length()<e-b+1)
                result=s.substr(b,e-b+1);
        }
    }
    return result;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值