在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