Wednesday, September 24, 2014

Longest Palindromic Substring

first method: dp

    string longestPalindrome(string s) {
        if(s.length()==0)
            return "";
        bool palin[1000][1000] = {false};
        int maxLen = 0;
        int maxstart=0;
        for(int i=s.length()-1;i>=0;i--)
        {
            for(int j=i;j<s.length();j++)
            {
                if(s[i]==s[j] && (j-i<=2 || palin[i+1][j-1]))
                {
                    palin[i][j] = true;
                    if(maxLen<j-i+1)
                    {
                        maxLen=j-i+1;
                        maxstart=i;
                    }
                }
            }
        }
        return s.substr(maxstart,maxLen); 
    }

second method: Time O(n), Space O(n) (Manacher's Algorithm)
 the code is generally adopted from leetcode, but i have changed a little to satisfy my understanding.  There is another flavor written by anniekim.

string preProcess(const string &s) {
  int n = s.length();

  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 = 0; i < n; 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]])//actually need to check if the index is in the range.
      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 = 0; i < n; i++) {
    if (P[i] > maxLen) {
      maxLen = P[i];
      centerIndex = i;
    }
  }
  delete[] P;
 
  return s.substr((centerIndex  - maxLen)/2, maxLen);
}

No comments:

Post a Comment