LeetCode5:Longest Palindromic Substring
题目:
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
解题思路:
主要有三种:
第一种:Manacher算法,也是最快的,时间复杂度为O(n)
第二种:DP算法,时间复杂度为O(n*n)
第三种:中心法,时间复杂度为O(n*n)
实现代码:
#include <iostream> #include <vector> using namespace std; /** Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. */ class Solution { public: //Manacher算法(O(n)) string longestPalindrome(string s) { string p; if(s.empty()) return p; int id = 0; int mx = 0; //以下对要操作的副本str进行格式化,使得其为奇数 string str("^"); for(int i = 0; i < s.size(); i++) { str += "#"; str += s[i]; } str += "#$"; vector<int> r(str.size(), 0); for(int i = 1; i < str.size()-1; i++) { if(mx > i) r[i] = min(r[2*id - i], mx - i); else r[i] = 1; while(str[i+r[i]] == str[i-r[i]])//为了防止越界,str头尾插入了'^'和'$'字符 r[i]++; if(r[i] + i > mx) { mx = r[i] + i; id = i; } } int maxlen = 0; int maxid = 0; for(int i = 1; i < str.size()-1; i++) { if(r[i] > maxlen) { maxlen = r[i]; maxid = i; } } //(maxid-1)/2为原字符串中最长回文字串中心字符位置 //(maxlen-1)/2为原字符串中最长回文子串半径 //maxlen-1为原字符串中最长回文字串长度 return s.substr((maxid-1)/2 - (maxlen-1)/2, maxlen-1); } //DP O(n*n) string longestPalindrome2(string s) { string p; if(s.empty()) return p; int len = s.size(); vector<vector<bool>> dp(len, vector<bool>(len, false));//dp[i][j]表示i~j的字串是否为回文串 int maxstart = 0; int maxlen = 1; for(int i = 0; i < len-1; i++) { dp[i][i] = true; if(s[i] == s[i+1]) { dp[i][i+1] = true; maxstart = i; maxlen = 2; } } for(int l = 3; l <= len; l++) { for(int i = 0; i < len-l+1; i++) { int j = i+l-1; if(s[i] == s[j] && dp[i+1][j-1]) { dp[i][j] = true; maxstart = i; maxlen = l; } } } return s.substr(maxstart, maxlen); } //中心法,以每一个字符作为回文串中心,向两边扩展 string longestPalindrome3(string s) { string p; if(s.empty()) return p; int len = s.size(); int maxstart = 0; int maxlen = 0; for(int i = 0; i < len; i++) { int l = i-1; int r = i+1; int tmpmax = 1;//已i为中心的回文串:奇数 while(l >= 0 && r < len && s[l--] == s[r++]) tmpmax++; if(maxlen < tmpmax*2 -1) { maxlen = tmpmax*2 -1; maxstart = l+1; } int l2 = i; int r2 = i+1; int tmpmax2 = 0;//已i和i+1为中心的回文串,偶数时 while(l2 >= 0 && r2 < len && s[l2--] == s[r2++]) tmpmax2++; if(maxlen < tmpmax2*2) { maxlen = tmpmax2*2; maxstart = l2+1; } } return s.substr(maxstart, maxlen); } }; int main(void) { string s("abbacdd"); Solution solution; string p = solution.longestPalindrome3(s); cout<<p<<endl; return 0; }
-----------------------我和我追猪的梦-----------------------------------------------------------------
作者:mickole