回文串问题

1.回文串的判断

#include <iostream>
#include <string.h>
using namespace std;
//回文串的判断
bool isPalindrome(const char* src)
{
    if(src == NULL)
        return true;
    int end = strlen(src)-1,begin = 0;
    while(begin < end)//从两边向中间判断,当然也可以从中间向两边判断
    {
        if(src[begin] != src[end])
            return false;
        begin ++;
        end --;
    }
    return true;
}
int main()
{
    string s1;
    cin>>s1;
    cout<<isPalindrome(s1.c_str());
    return 0;
}

 

2.最长回文子串

中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,这样来找最长的子回文串。算法复杂度为O(N^2)。
但是要考虑两种情况:
1、像aba,这样长度为奇数。
2、像abba,这样长度为偶数。
int expandAroundCenter(const char* src,int left,int right)//从中间往两头判断最长回文串
{
    int length = strlen(src);
    while(left >= 0 && right < length && src[left] == src[right])
    {
        left --;
        right ++;
    }
    return right - left - 1;
}

void LongestPalindromeCenter(const char* src)
{
    if(src == NULL)
        return;
    int length = strlen(src);
    int i,maxLen = 1,begin = 0,end = 0;
    for(i = 0;i < length;i++)
    {
        int len = expandAroundCenter(src,i,i);//针对奇数
        if(len > maxLen)
        {
            maxLen = len;
            begin = i - ((len-1) >> 1);
            end = i + ((len-1) >> 1);
        }
        len = expandAroundCenter(src,i,i+1);//针对偶数
        if(len > maxLen)
        {
            maxLen = len;
            begin = i - (len >> 1) + 1;
            end = i + (len >> 1);
        }
    }
    for(i = begin;i <= end;i++)
        cout<< src[i];
    cout << endl;
}


int main()
{
    string s1;
    cin>>s1;
    //cout<<isPalindrome(s1.c_str());
    LongestPalindromeCenter(s1.c_str());
    return 0;
}

动态规划法:

回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文字符串,那么P[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。这样需要额外的空间O(N^2),算法复杂度也是O(N^2)。

首先定义状态方程和转移方程:

P[i,j]=0表示子串[i,j]不是回文串。P[i,j]=1表示子串[i,j]是回文串。

P[i,j]{=P[i+1,j-1] , if(s[i]==s[j])

           =0 , if(s[i]!=s[j])

posted @ 2017-08-30 22:25  home普通的人  阅读(281)  评论(0编辑  收藏  举报