Longest Palindromic Substring

Description:

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.


算法1:

动态规划。复杂度是 O(n^2)

f[i][j] 表示 字串[i---j]是否是一个回文。

    f[i][j] = true,         i = j

             s[i] == s[j],  j = i+1

            (s[i] == s[j]) && f[i+1][j-1], j > i+1;

    string longestPalindrome(string s) {
        const int n=s.size(); 
        int start(0), max_len(1);
        bool f[n][n];
        fill_n(&f[0][0], n*n, false);
        
        for(int i=n-1; i>=0; --i)
        {
          f[i][i] = true;
          for(int j=i+1; j<n; ++j)
          {
              f[i][j] = (s[i]==s[j] ? true:false) && (j-i < 2 || f[i+1][j-1]);
                 
              if(f[i][j] && j-i+1 > max_len){
                  start = i;
                  max_len = j-i+1;
              }
          }
        }
        return s.substr(start, max_len);
    }
};

算法2: 

枚举回文的中心,向两边扩展。。复杂度 O(N^2)

class Solution {
public:
// start from center
string longestPalindrome(string s)
{
  if(s.size() < 2) return s;
  string longest;
  string p;

  for(int i=0; i<s.size()-1; ++i){
    //palindrome is odd
    p = expandFromCenter(s, i, i);
	if(p.size() > longest.size())
	  longest = p;

	//palindrome is even
    p = expandFromCenter(s, i, i+1);
	if(p.size() > longest.size())
	  longest = p;
  }

  return longest;
}
private:
string expandFromCenter(string s, int c1, int c2)
{
  int l(c1), r(c2);
  while(l >= 0 && r < s.size() && s[l] == s[r]){
    -- l;
    ++ r;
  }
  return s.substr(l+1, r-l-1);
}
};


3.  Manacher 算法, 复杂度 O(n)

 参考  http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html

// Manacher algorithm

// Transform S into T
// For example, S = "abba", T = "^#a#b#b#a#$"
// ^ and $ signs are sentinels appended to each string
// to avoid bound checking
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 longestPalindromeManacher(string s)
{
  string T = preProcess(s);
  int n = T.length();
  vector<int> p(n, 0);
  int C = 0, R = 0;
  for (int i = 1; i < n-1; ++i){
    int i_mirror = 2*C-i;

	p[i] = (i < R) ? 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(p[i] + 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;
	}
  }
  return s.substr((centerIndex - 1 - maxLen)/2 , maxLen);
}


你可能感兴趣的:(LeetCode,Manacher,最长回文字串)