Longest Palindromic Substring (最长回文子串)

给定一个子符串S,找出最长回文子串。你可以假定S的最大长度为1000,并且存在唯一最长回文子串。

题目源文,请见:https://oj.leetcode.com/problems/longest-palindromic-substring/


 动态规划,O(N2) time and O(N2) space:

 考虑字符串“ababa”。如果我们已经知道“bab”是回文,很明显可以推出“ababa” 一定是回文子串。因为其左边和右边的字符是相等的。

 更正式的表术为:

P[ i, j ] ← true 如果子串 S i … S j 是回文, 否则 false.

 因此,

P[ i, j ] ← ( P[ i+1, j-1 ]  and S i = S j )

 初始条件为:

P[ i, i ] ← true
P[ i, i+1 ] ← ( S i = S i+1 )

 至此很直观的得到一个动态规划思路,我们可以首先找到一个和两个字符长度的回文子串作为开始,然后再找到全部长度为3回文子串,如此重复下去...

 算法的时间复杂度为O(N2),空间复杂度O(N2),用来存储表格P。

string longestPalindromeDP(string s) {
  int n = s.length();
  int longestBegin = 0;
  int maxLen = 1;
  bool table[1000][1000] = {false};
  for (int i = 0; i < n; i++) {
    table[i][i] = true;
  }
  for (int i = 0; i < n-1; i++) {
    if (s[i] == s[i+1]) {
      table[i][i+1] = true;
      longestBegin = i;
      maxLen = 2;
    }
  }
  for (int len = 3; len <= n; len++) {
    for (int i = 0; i < n-len+1; i++) {
      int j = i+len-1;
      if (s[i] == s[j] && table[i+1][j-1]) {
        table[i][j] = true;
        longestBegin = i;
        maxLen = len;
      }
    }
  }
  return s.substr(longestBegin, maxLen);
}


中心扩展O(N2) time and O(1) space:

经过观察,我们会发现回文是围绕其中心左右对称的。因此,回文可以从中心向外一步步扩张。这样的中心有2N-1个。

你也许会问,为什么是2N-1而不是N个?原因则是回文的中心可以位于两个字符的中间。这样的回文有偶数个字符(例如“abba”),它的中心就位于两个‘b’之间。

从中心扩展回文需要花费O(N)时间,整体上的时间复杂度为O(N2)。

string expandAroundCenter(string s, int c1, int c2) {
  int l = c1, r = c2;
  int n = s.length();
  while (l >= 0 && r <= n-1 && s[l] == s[r]) {
    l--;
    r++;
  }
  return s.substr(l+1, r-l-1);
}
 
string longestPalindromeSimple(string s) {
  int n = s.length();
  if (n == 0) return "";
  string longest = s.substr(0, 1);  // a single char itself is a palindrome
  for (int i = 0; i < n-1; i++) {
    string p1 = expandAroundCenter(s, i, i);
    if (p1.length() > longest.length())
      longest = p1;
 
    string p2 = expandAroundCenter(s, i, i+1);
    if (p2.length() > longest.length())
      longest = p2;
  }
  return longest;
}


O(N)的方案是否存呢?答案是肯定,请参见下一节的 Manacher方法。

原文:http://leetcode.com/2011/11/longest-palindromic-substring-part-i.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值