https://leetcode.com/problems/longest-palindromic-substring/
暴力查找:由于找到字符串的所有字串的时间复杂度为O(n^2),判断一个字符串是否为回文串需要遍历,时间复杂度为O(n),所以这个算法的时间复杂度为O(n^3)
对于任意一个长度为n的字符串,总是存在最长的回文字串,对于这个回文字串而言,它的中心只有2n-1种可能存在的位置。它可以位于某一个字符上(如”aba”的回文中心在字符b上),这一共有n种情况。回文中心也可以在两个字符的缝隙中(如”aa”的回文中心在两个字符a之间),这一共有n-1种情况。
因此我们可以考虑这2n-1个位置上,对应的最大回文子串长度。如果不是回文串(如”ab”这种情况),那么最大回文子串长度就是0。这个过程的时间复杂度为O(n),由于需要遍历这2n-1个位置,整个算法的时间复杂度为O(n^2)。
我在做此题时,为了偷懒,把两种可能合并起来了,结果反而导致代码量大幅度提升。不过修修补补也通过了测试,代码如下:
class Solution {
public:
string longestPalindrome(string s) {
int longestLength = 1, startPos = 0;
for(int i = 0; i < s.size(); i++){
for(int j = i - 1, tempLength = 1, flag = 0; j > -1; --j){
if(2 * i - j - flag < s.size()){
if(s[j] == s[2 * i - j - flag]){
tempLength += 2;
if((j == 0 || 2 * i - j - flag == s.size() - 1) && tempLength >= longestLength){
longestLength = tempLength;
startPos = j;
}
}
else if(s[j] == s[i] && s.substr(j, i-j+1) == string(i-j+1, s[j])){
++tempLength;
++flag;
if(tempLength > longestLength){
longestLength = tempLength;
startPos = j;
}
}
else{
if(tempLength > longestLength){
longestLength = tempLength;
startPos = j + 1;
}
break;
}
}
else if(s[j] == s[i] && tempLength == longestLength){
++longestLength;
startPos = j;
break;
}
else{
break;
}
}
}
return s.substr(startPos, longestLength);
}
};
刚刚那个算法其实还可以继续优化,关键在于,遍历这2n-1个位置时,每次都要重新计算最大回文子串长度,但由于回文串的对称性,有些计算其实是不必要的。
首先把字符串用一个特殊符号,比如#填充。比如字符串S = “abaaba”,填充后的新字符串T = “#a#b#a#a#b#a#”
观察T的每个位置上的最长回文子串长度P,我们发现一个规律:
T = # a # b # a # a # b # a #
P = 0 1 0 3 0 1 6 1 0 3 0 1 0
即这个数组P也是对称的。
但是这个规律并不总是成立,假设当前正在计算的回文子串的中心为C,比如在上一个例子中C = 6,即字符串中心的那个#。对于第i个字符串,记i’ = 2C - i,即i’ 是 i 关于中心C对称的点。只有当p[i’] + i 不超过这个回文串最右边边界时,p[i]才等于p[i’],否则p[i] >= p [i’],此时我们需要拓展这个回文子串。新的中心C = i,并重新计算最右边的边界。
这种方法的巧妙之处在于,对于p[i]的计算,不必重新向两端遍历,而是充分利用了之前的计算结果,只有在无法利用计算结果时,才会选择向右拓展。虽然依然需要O(n)的时间复杂度来遍历2n-1个位置,但是在计算每个位置的最大回文子串长度时,要么根据对称性直接得出结果,时间复杂度为O(1),要么向右拓展,进行循环。但是虽然这里进行了内部循环,但是由于总是向右拓展,总循环次数一定不会超过n,所以整个算法的的时间复杂度为O(n)+ O(n) = O(n)。
Manacher算法非常巧妙的利用了对称性减少计算量,不过也不容易想到,实现起来也有一些细节需要考虑。如果算法对时间要求非常高,可以选择这个算法
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/abc649395594/article/details/48877491
内容来源于网络,如有侵权,请联系作者删除!