回文串問題
阿新 • • 發佈:2017-08-31
中間 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(constchar* 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])
回文串問題