[leetcode] Longest Palindromic Substring 多种解法

非常经典的题目,求字符串中的最长回文子串。

(1)最朴素的解法 ---暴力 复杂度O(N³)

这也是最easy想到的方法。最外层循环枚举起点i,第二层循环从i+1開始向后枚举,第三层推断是不是回文串。最后取最长子串的返回。

代码比較简单,这里没有列出。

(2)中心扩展法。复杂度O(N²)

枚举每个字符作为中心点向左右扩展。

可是这里要注意,对于每一次扩展要分奇偶两种情况。

否则可能会漏掉情况。

一发现不满足的情况立即break进行下一个中心字符的推断,代码例如以下:

class Solution {
public:
    string longestPalindrome(string s) {
        string ans;
        int len=s.length();
        int maxLength=-1,CurLen,Sbegin;
        for(int i=0;i<len;i++)
        {
                int left=i-1,right=i+1;
                while(left>=0&&right<len&&s[left]==s[right])//奇数情况 
                {
                        CurLen=right-left+1;
                        if(CurLen>maxLength)
                        {
                        	maxLength=CurLen;
                        	Sbegin=left;
                        }
                        left--,right++;
                }
                
                left=i,right=i+1;
                while(left>=0&&right<len&&s[left]==s[right])//偶数情况 
                {
                        CurLen=right-left+1;
                        if(CurLen>maxLength)
                        {
                        	maxLength=CurLen;
                        	Sbegin=left;
                        }
                        left--,right++;
                }
               
        }
        ans=s.substr(Sbegin,maxLength);
        return ans;

    }
};

(3)Manacher算法。复杂度仅仅有O(n)

 详细算法介绍:点击打开链接

附上静止的代码:

class Solution {
public:
   string preProcess(string s) {  
     int  n = s.length();  
     if (n == 0) return "^$";  
     string ret = "^";  
     for (int i = 0; i < n; i++)  
        ret += "#" + s.substr(i, 1);  
     ret += "#$";  
    return ret;  
}  
   
string longestPalindrome(string s) {  
     string T = preProcess(s);  
     int n = T.length();  
     int *P = new int[n];  
     int C = 0, R = 0;  
     for (int i = 1; i < n-1; i++) {  
    int i_mirror = 2*C-i; // equals to i' = C - (i-C)  
    
    P[i] = (R > i) ? min(R-i, P[i_mirror]) : 0;  
  
    // Attempt to expand palindrome centered at i  
    while (T[i + 1 + P[i]] == T[i - 1 - P[i]])  
      P[i]++;  
   
    // If palindrome centered at i expand past R,  
    // adjust center based on expanded palindrome.  
    if (i + P[i] > R) {  
      C = i;  
      R = i + P[i];  
    }  
  }  
  // Find the maximum element in P.  
  int maxLen = 0;  
  int centerIndex = 0;  
  for (int i = 1; i < n-1; i++) {  
    if (P[i] > maxLen) {  
      maxLen = P[i];  
      centerIndex = i;  
    }  
  }  
  delete[] P;  
    
  return s.substr((centerIndex - 1 - maxLen)/2, maxLen);  
}  
};

(4)后缀树的解法,待补充




原文地址:https://www.cnblogs.com/slgkaifa/p/6742420.html