由leecode’最长回文子串‘题,感受算法对计算效率影响

在leecode上做了一道从长度不超过1000的字符串中寻找回文。

题目见:https://leetcode-cn.com/problems/longest-palindromic-substring/description/

 

一开始自然想到用暴力搜索的方法,依次便利所有可能为回文的字符串,如对于长度为999的字符串,依次搜索长度为1~999,如此一来虽然可以实现功能但由于其时间复杂度达O(n^3)故而十分不便利。

时间复杂度计算,此算法设有长度为n的字符,需依次搜索长度为1~n的潜在回文子字符串。而在搜索每个潜在回文字符串时,其大约需搜索n*(n-1)/2次,故而总的时间复杂度约为O(n^3)。实际计算长度为999的字符串共花去了越12s的时间。

后来经查看了leecode的解答思路,应尽可能避免重复计算,说明如下:

而如此花去的时间仅有

由此初步感受了合理算法对计算效率的提升。

 

1、暴力所搜的实现:

class Solution:

    def longestPalindrome(self,s):

        s=list(s)

        s_rever=[]

        for i in range(len(s)):

            s_rever.append(len(s)-i-1)

       

        hw=[]

        for hw_len in range(len(s)):     

            hw_len=hw_len+1

            hs=[]

            for i in range(len(s)):

                hs=s[i:i+hw_len]

 

                if len(hs)!=hw_len:

                    continue

               

                if hw_len%2==0:

                    s_1=hs[:(len(hs)//2)]

#                    print(hs,s_1)

                    s_2=hs[len(hs)//2:]

                    s_1_rever=[]

                    for i in range(len(s_1)):

                        s_1_rever.append(s_1[len(s_1)-i-1])                   

                    if s_2==s_1_rever:

                        hw=hs

                        break

                   

                else:

                    s_1=hs[:len(hs)//2]

                    s_2=hs[len(hs)//2+1:]

                    s_1_rever=[]

                    for i in range(len(s_1)):

                        s_1_rever.append(s_1[len(s_1)-i-1])         

                    if s_2==s_1_rever:

                        hw=hs

                        break 

 

        hw=''.join(hw)

        return hw

 

 

2、动态搜索的实现:

class Solution:

    def longestPalindrome(self,s):

        s=list(s)

       

        if s==[]:

            return ""

       

        s_rever=[]

        for i in range(len(s)):

            s_rever.append(len(s)-i-1)

       

        hw=[]

 

        hw_list=[]

#找出2回文  

        for s_i in range(len(s)):

            hs=s[s_i:s_i+2]

           

            if len(hs)!=2:

                continue

 

            s_1=hs[:(len(hs)//2)]

#                    print(hs,s_1)

            s_2=hs[len(hs)//2:]

            s_1_rever=[]

            for i in range(len(s_1)):

                s_1_rever.append(s_1[len(s_1)-i-1])                   

            if s_2==s_1_rever:

                hw_list.append([s_i,s_i+2])

 

#找出3回文

        for s_i in range(len(s)):

            hs=s[s_i:s_i+3]

           

            if len(hs)!=3:

                continue

            s_1=hs[:(len(hs)//2)]

            s_2=hs[len(hs)//2+1:]

            s_1_rever=[]

            for i in range(len(s_1)):

                s_1_rever.append(s_1[len(s_1)-i-1])                   

            if s_2==s_1_rever:

                hw_list.append([s_i,s_i+3])

           

        hw_list_new=[]

        while 1:

            for hw_seed in hw_list:

                head=hw_seed[0]-1

                end=hw_seed[1]

                hw_seed_len=end-head

                if (head<0) or (end>len(s)-1) :

                    continue

                if (s[head]==s[end]):

                    hw_list_new.append([head,end+1])

            if  hw_list_new==[]:

                break

            else:

                hw_list=hw_list_new

                hw_list_new=[]

        if hw_list==[]:

            sss=s[-1]

        else:

            sss=''.join(s[hw_list[-1][0]:hw_list[-1][1]])

 

        return sss