1. 程式人生 > >回文串問題

回文串問題

中間 rom pan center 動態規劃法 ons 字母 長度 pre

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])

回文串問題