【回文子串的个数】HDU1544Palindromes【字符缩距/奇偶判断】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1544

Problem Description
A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string is read from right to left.

Now give you a string S, you should count how many palindromes in any consecutive substring of S.
 

Input
There are several test cases in the input. Each case contains a non-empty string which has no more than 5000 characters.

Proceed to the end of file.
 

Output
A single line with the number of palindrome substrings for each case. 
 

Sample Input
   
   
   
   
aba aa
 

Sample Output
   
   
   
   
4 3

奇偶回文判断AC代码: 时间复杂度O(n^2)

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main()
{
    string s;
    cin.sync_with_stdio(false);
    while(cin>>s){
        int len=s.size();
        int ans=len;        //  长度为1的个数;
        for(int i=0;i<len;i++){
            int l=i-1,r=i+1;        //  以i为中心的奇数长度回文子串的判断;
            while(l>=0&&r<len&&s[l]==s[r]){
                l--,r++;
                ans++;
            }
            l=i,r=i+1;              //  以i为中心的偶数长度回文子串的判断;
            while(l>=0&&r<=len&&s[l]==s[r]){
                l--,r++;
                ans++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

字符缩距AC代码: 字符串所有字符都不同,最差复杂度O(n^2) 相对于奇偶判断效率还是更高的

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int Hash[5500];
int main()
{
    string s;
    cin.sync_with_stdio(false);
    while(cin>>s){
        memset(Hash,0,sizeof(Hash));
        string str="";
        str+=s[0];
        int k=0;
        Hash[0]=1;
        for(int i=1;i<s.size();i++){
            if(s[i]==s[i-1])
                Hash[k]++;
            else{
                k++;
                Hash[k]=1;
                str+=s[i];
            }
        }
        k++;
        int ans=0;
        for(int i=0;i<k;i++)
            ans+=(1+Hash[i])*Hash[i]/2;
        for(int i=0;i<k;i++){
            int a=i-1;
            int b=i+1;
            if(a<0||b>=k) continue;     //  一言不合就跳过
            int flag=0;
            while(str[a]==str[b]&&Hash[a]==Hash[b]){
                ans+=Hash[a];
                a--;
                b++;
                if(a<0||b>=k){
                    flag=1;
                    break;
                }
            }
            if(flag==0&&str[a]==str[b]){
                ans+=min(Hash[a],Hash[b]);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}



你可能感兴趣的:(【回文子串的个数】HDU1544Palindromes【字符缩距/奇偶判断】)