最长回文子串

来源:互联网 发布:linux ntpclient 编辑:程序博客网 时间:2024/06/17 19:09

1 题目

Given a stringS, find the longest palindromic substring in S. You may assume that the maximumlength of S is 1000, and there exists one unique longest palindromic substring.

2 分析

若字符串str为对称串则称str为回文 (palindromic) 串;若str中子串subStr为对称串,则subStr为str的回文子串。例如字符串str=”abbacde”,其中子串subStr=”abba”为回文子串,且str中不存在比subStr更长的回文子串,则subStr为str的最长回文子串。

2.1 一个比较笨的想法

最长公共子串:给定两个字符串,求出它们之间最长的相同子字符串的长度。因此可以先求出题目中字符串s的逆向字符串rs,然后求s与rs的最长公共子串,但是此时公共子串必须满足在s中的位置与在rs中的位置相对应。

此时问题的时间复杂度与最长公共子串相同。

 

另外,[http://www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html]给出了时间复杂度为O(n)的算法,研究中……

2.2 直接法

从字符串中的每一个位置开始正向与逆向遍历比较以此为中心的回文子串的长度。该方法的求解时间复杂度为O(n2)。

 

3 实现

(1) 最长公共子串参考http://www.cnblogs.com/ider/p/longest-common-substring-problem-optimization.html,实现如下:

string longestPalindrome(strings){      string result;      string rs;      int size = s.size();      while (size > 0)      {             rs.push_back(s[--size]);      }      int lenth = 0;      int pos = findLongestCommanSubString(s,rs, lenth);       while (lenth-- > 0)      {             result.push_back(s[pos++]);      }       return result;} int findLongestCommanSubString(conststring &s1, const string &s2, int &lenth){      int pos = 0;       int size1 = s1.size();      int size2 = s2.size();      if (0 == size1 || 0 == size2)      {             return 0;      }       vector<vector<int> > table(2,vector<int>(size2, 0));           int comparisons = 0;      for (int j = 0; j < size2; ++j)      {             ++comparisons;             if (s1[0] == s2[j])             {                    table[0][j] = 1;                    if (0 == lenth)                    {                           lenth = 1;                           pos = 0;                    }             }      }       for (int i = 1; i < size1; ++i)      {             int cur = ((i & 1) == 1);             int pre = ((i & 1) == 0);             table[cur][0] = 0;             if (s1[i] == s2[0])             {                    table[cur][0] = 1;                    if (0 == lenth)                    {                           lenth = 1;                           pos = i;                    }             }                         for (int j = 1; j < size2; ++j)             {                    if (s1[i] == s2[j])                    {                           table[cur][j] =table[pre][j - 1] + 1;                           if (lenth <table[cur][j])                           {                                  if (size1 - i- 1 == j - table[cur][j] + 1)                                  {                                         lenth =table[cur][j];                                         pos = i- lenth + 1;                                  }                                                            }                    }                    else                    {                           table[cur][j] = 0;                    }             }      }       return pos;}


(2) 对应2.2,代码如下:

string longestPalindrom(strings){      int l, r;      l = r = 0;      int len = s.size();      int start = 0;      int maxLen = 0;      if (len <= 1)      {             return s;      }       int tempLen = 0;       for (int i = 0; i < len; ++i)      {             l = i - 1;             r = i + 1;             tempLen = 1;             while (l >= 0 && r <=len - 1 && s[l] == s[r])             {                    tempLen += 2;                    if (tempLen > maxLen)                    {                           start = l;                           maxLen = tempLen;                    }                    --l;                    ++r;             }              l = i;             r = i + 1;             tempLen = 0;             while (l >= 0 && r <=len - 1 && s[l] == s[r])             {                    tempLen += 2;                    if (tempLen > maxLen)                    {                           start = l;                           maxLen = tempLen;                    }                    --l;                    ++r;             }      }      string res = s.substr(start, maxLen);      return res;}


0 0