1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
const int maxn = 1010; int PHash[maxn]; int SHash[maxn]; int BP[maxn]; const int M = 1e9 + 7; const int B = 233; typedef long long ll;
void initHash(string &str, int n){ for(int i = 0, val = 1; i < maxn; ++i){ BP[i] = val, val = ((ll)val * B) % M; } for(int i = 0, val = 0; i < n; ++i){ PHash[i] = val = ((ll)val * B + str[i]) % M; } for(int i = n-1, val = 0; i >=0; --i){ SHash[i] = val = ((ll)val * B + str[i]) % M; } } int segPHash(int i, int j){ int ans = PHash[j]; if(i != 0) ans = (ans - (ll)PHash[i - 1] * BP[j-i+1]) % M; if(ans < 0) ans += M; return ans; } int segSHash(int i, int j, int n){ int ans = SHash[i]; if(j != n-1) ans = (ans - (ll)SHash[j + 1] * BP[j-i+1]) % M; if(ans < 0) ans += M; return ans; }
class Solution { public: string longestPalindrome(string& s) {
if(!s.size()) return s; int n = s.size(), maxLen = 1, pos = 0, lastLen = 1; initHash(s, n); for(int i = 1; i < n; ++i){ int k = min(i + 1, lastLen + 2); lastLen = 1; while(k>1){ int len = (k >> 1) + (k & 1); int lh = segPHash(i-k+1, i-k+len); int rh = segSHash(i-len+1, i,n); if(lh == rh){ if(k > maxLen) maxLen = k, pos = i; lastLen = k;break; } --k; } } return s.substr(pos-maxLen+1,maxLen); } };
|