题目:
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.
分析与解答:
求字符串S的最长回文子串。
暴力法的时间复杂度为O(n^3),不予考虑。
方法1.计算以S[i]为中心的最大回文串,方法是逐个字符比较,复杂度O(n^2)。
方法2.S和S的反向字符串的LCS就是最长回文子串,用DP,空间复杂度O(n)时间复杂度O(nlogn)。
今天突然发现,这个方法2是不可行的,比如ABC12CBA8998就是个反例。如果真想用这种方法,还需要判断LCS的在每个字符串中的位置。
方法3.一种manacher的线性算法。复杂度O(n).
方法4.后缀树。构建这种数据结构比较复杂,过两天再研究一下。
采用方法3,算法的思想很简单就不详细写了。
class Solution { public: string longestPalindrome(string s) { int strLen = s.length(), resIndex = 0, id = 0, maxRight = 0, palRad[2000]; char str[2000]; //扩展后的字符串 str[0] = '?'; //对字符串进行预处理 for (int i = strLen; i >= 0; i--) { str[i * 2 + 2] = s[i]; str[i * 2 + 1] = '#'; } for (int i = 2; i < strLen * 2 + 1; i++) { if (palRad[id] + id > i) //最右能达到的距离包含了i palRad[i] = min(palRad[id] + id - i, palRad[id * 2 - i]); else palRad[i] = 1; //半径为1,即仅包含自己本身 while (str[i - palRad[i]] == str[i + palRad[i]]) palRad[i]++; if (id + palRad[id] < i + palRad[i]) id = i; if (maxRight < palRad[i]) { maxRight = palRad[i]; resIndex = i - palRad[i]; } } return s.substr(resIndex / 2, maxRight - 1); } };