zoukankan      html  css  js  c++  java
  • LeetCode#5 Longest Palindromic Substring

    Problem Definition:

    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.

    Solution:

    1) 暴力。把所有的子串全找出来,然后验真是否回文。找子串耗时O(n^2)来确定起点和终点;验真回文耗时O(n)。于是得到一个O(n^3)的算法(或许不叫算法)。

     1 def longestPalindrome(s):
     2         #brute-force TLE
     3         mag,subLen,maxLen,subStr=len(s),2,1,[0,1]#[begin,length]
     4         while subLen<=mag:
     5             for i in range(mag-subLen+1):
     6                 if self.isPal(s[i:i+subLen]):
     7                     maxLen=max(maxLen,subLen)
     8                     subStr=[i,maxLen]
     9             subLen+=1
    10         return s[subStr[0]:subStr[0]+subStr[1]]
    11 
    12 def isPal(s):
    13         head,rear=0,len(s)-1
    14         while head<=rear:
    15             if s[head]!=s[rear]:
    16                 return False
    17             head+=1
    18             rear-=1
    19         return True

    2)动态规划。任何长度大于1的回文,必然可以由更小的回文扩展而来。用s[i....j]表示从i到j的这个子串,则有:

      1._如果s[i+1...j-1]是回文,且s[ i ]==s[ j ],则s[i...j]是回文。

      2._如果s[i+1...j-1]不是回文,或者s[ i ]!=s[ j ],则s[i...j]不是回文。

        可以用一个表来记录子串是否是回文。tb=[ n ][ n ], tb[ 2 ][ 2 ]==True表示从下标2开始到下标2结束的

      子串(就是一个字符)是回文,tb[4][7]==True表示从下标4到下标7的串是回文。

        这个解法耗时O(n^2),空间复杂度也是O(n^2)。

     1 def longestPalindrome(s):
     2         #dp
     3         begin,maxLen=0,1
     4         tb=[[False]*len(s)]*len(s)
     5         for i in range(len(s)): #subLen=1
     6             tb[i][i]=True
     7         for i in range(len(s)-1):
     8             if tb[i][i]==tb[i][i+1]:  #subLen=2
     9                 begin=i
    10                 maxLen=2
    11         for subLen in range(3,len(s)+1): #subLen=[3-->len(s)]
    12             for i in range(len(s)-subLen+1):  #begin index
    13                 j=i+subLen-1                  #end index
    14                 if s[i]==s[j] and tb[i+1][j-1]==True:
    15                     tb[i][j]=True
    16                     begin=i
    17                     maxLen=subLen
    18         return s[begin:begin+maxLen]

    3)从回文串对称轴扩展。我们知道回文字符串是对称的,因此任何一个回文字符串都可以从它的对称轴处开始扩展而来。

       这里要注意的是,回文串的长度可能是奇数或偶数。奇数长度字符串的对称轴上是一个字符,比如aba;偶数长度字

       符串对称轴上则是空隙,比如abba。因此有2n-1个位置可以作为对称轴(n个字符,n-1个空隙)。

       此方法耗时O(n^2),空间复杂度为常数。

     1 def longestPalindrome(s):
     2         lgst=s[0]
     3         for i in range(len(s)-1):
     4             s1=self.expCenter(s, i, i)
     5             if len(s1)>len(lgst):
     6                 lgst=s1
     7             s2=self.expCenter(s, i, i+1)
     8             if len(s2)>len(lgst):
     9                 lgst=s2
    10         return lgst
    11 
    12 def expCenter(self, s, lft, rgt):
    13         while lft>=0 and rgt<len(s) and s[lft]==s[rgt]:
    14             lft-=1
    15             rgt+=1
    16         return s[lft+1:rgt]

    4)还有更优的解法吗? Manacher算法可以达到线性的时间复杂度。

  • 相关阅读:
    软件工程第一次作业
    Python正则表达式学习摘要
    个人作业——软件工程实践总结作业
    个人作业——软件评测
    软件工程实践2019第五次作业--结对编程的实现
    软件工程实践2019第四次作业
    软件工程实践2019第三次作业
    软件工程实践2019第二次作业
    软件工程实践2019第一次作业
    个人作业——软件工程实践总结&个人技术博客
  • 原文地址:https://www.cnblogs.com/acetseng/p/4683120.html
Copyright © 2011-2022 走看看