python實現求最長回文子串長度

2022-10-04 20:27:20 字數 4512 閱讀 2893

給定乙個字串,求它最長的回文子串長度,例如輸入字串'35534321',它的最長回文子串是'3553',所以返回4。

最容易想到的辦法是列舉出所有的子串,然後一一判斷是否為回文串,返回最長的回文子串長度。不用我說,列舉實現的耗時是我們無法忍受的。那麼有沒有高效查詢回文子串的方法呢?答案當然是肯定的,那就是中心擴充套件法,選擇乙個元素作為中心,然後向外發散的尋找以該元素為圓心的最大回文子串。但是又出現了新的問題,回文子串的長度即可能是基數,也可能好是偶數,對於長度為偶數的回文子串來說是不存在中心元素的。那是否有一種辦法能將奇偶長度的子串歸為一類,統一使用中心擴充套件法呢?它就是manacher演算法,在原字串中插入特殊字元,例如插入#後原字串變成'#3#5#5#3#4#3#2#1#'。現在我們對新字串使用中心擴充套件發即可,中心擴充套件法得到的半徑就是子串的長度。

現在實現思路已經明確了,先轉化字串'35534321'  ---->  '#3#5#5#3#4#3#2#1#',然後求出以每個元素為中心的最長回文子串的長度。以下給出python實現:

#!/usr/bin/python

# -*- coding: utf-8 -*-

def max_substr(string):

s_list = [s for s in string]

string = '#' + '#'.join(s_list) + '#www.cppcns.com'

max_length = 0

length = len(string)

for index in range(0, length):

r_length = get_length(string, index)

if max_length < r_length:

max_length = r_length

return max_length

def get_length(string, index):

# 迴圈求出index為中心的最長回文字串

length = 0

r_ = len(string)

for i in range(1,index+1)xhdfiv:

if index+i < r_ and string[index-i] == string[index+i]:

length += 1

else:

break

return length

if __name__ == "__main__":

result = max_substr("35534321")

print result

功能已經實現了,經過測試也沒有bug,但是我們靜下心來想一想,目前的解法是否還有優化空間呢?根據目前的解法,我們求出了『35534321『中每個元素中心的最大回文子串。當遍歷到'4'時,我們已經知道目前最長的回文子串的長度max_length是4,這是我們求出了以4為中心的最長回文子串長度是3,它比max_length要小,所以我們不更新max_length。換句話說,我們計算以4為中心的最長回文字串長度是做了無用功。這就是我們要優化的地方,既然某個元素的最長的回文子串長度並沒有超過max_length,我們就沒有必要計算它的最長回文子串,在遍歷乙個新的元素時,我們要優先判斷以它為中心的回文子串的長度是否能超越max_length,如果不能超過,就繼續遍歷下乙個元素。以下是優化後的實現:

#!/usr/bin/python

# -*- coding: utf-8 -*-

def max_substr(string):

s_list = [s for s in string]

string = '#' + '#'.join(s_list) + '#'

max_length = 0

length = len(string)

for index in range(0, length):

r_length = get_length2(string, index, max_length)

if max_length < r_length:

max_length = r_length

return max_length

def get_length2(string, index, max_length):

# 基於已知的最長字串求最長字串

# 1.中心+最大半徑超出字串範圍, return

r_ = len(string)

if index + max_length > r_:

return max_length

# 2.無法超越最大半徑, return

l_string = string[index - max_length + 1 : index + 1]

r_string = string[index : index + max_length]

if l_string != r_string[::-1]:

return max_length

# 3.計算新的最大半徑

result = max_length

for i in range(max_length, r_):

if index-i >= 0 and index+i < r_ and string[index-i] == string[index+i]:

result += 1

else:

break

return result - 1

if __name__ == "__main__":

result = max_www.cppcns.comsubstr("35534321")

print result

那麼速度到底提公升了多少呢,以字串1000個『1'為例,優化前的演算法執行時間為0.239018201828,優化後為0.0180191993713,速度提公升了10倍左右

/usr/bin/python /users/hakuippei/pycharmprojects/untitled/the_method_of_programming.py

0.239018201828

0.0180191993713

再給大家分享乙個例項:

#!usr/bin/env python

#encoding:

'''__author__:沂水寒城

功能:尋找最長回文子串行

'''def slice_window(one_str,w=1):

'''滑窗函式

'''res_list=

for i in range(0,len(one_str)-w+1):

res_list.append(one_str[i:i+w])

return res_list

def is_huiwen(one_str_list):

'''輸入乙個字串列表,判斷是否為回文序列

'''

if len(one_str_list)==1:

return true

else:

half=len(one_str_list)/2

if len(one_str_list)%2==0:

first_list=one_str_list[:half]

second_list=one_str_list[half:]

else:

first_list=one_str_list[:half]

second_list=one_str_list[half+1:]

if first_list==second_list[::-1]:

return true

else:

return false

def find_longest_sub_palindrome_str(one_str):

'''主函式,尋找最長回文子串行

'''all_sub=

for i in range(1,len(one_str)):

all_sub+=slice_window(one_str,i)

all_sub.append(one_str)

new_list=

for one in all_sub:

if is_huiwen(list(one)):

new_list.append(one)

new_list.sort(lambda x,y:cmp(len(x),len(y)),reverse=true)

print new_list[0]

if __name__ == '__main__':

one_str_list=['uabcdcbaop','abcba','dmfdkgbbfdlg'www.cppcns.com,'mnfkabcbadk']

for one_str in one_str_list:

find_longest_sub_palindrome_str(one_str)

結果如下:

abcdcba

abcba

bb abcba

[finished in 0.3s]

本文標題: python實現求最長回文子串長度

本文位址:

求最長回文子串

求最長回文子串,大概有以下幾種方法 1 錯誤!先翻轉再求最長公共子串 例如 abcdafdcba abcd x 即原串中包含翻轉串的子串時 2 暴力 遍歷每個字串,然後判斷是否是回文子串並記錄最長資訊 時間複雜度o n 3 3 動態規劃 時間複雜度o n 2 空間複雜度o n 2 dp i j 表示...

求最長回文子串

1.第一種方法 o n 2 動態規劃,用s i j 表示從i到j是最長回文字串,用乙個table i j 記錄字串從i到j是否為回文,這樣的話,從底部向上,table i i true 另外如果s i s i 1 則table i i 1 true,然後長度從3開始,如果s i 1 s j 1 則就...

求最長回文子串

利用中心擴充套件法求最長回文子串演算法複雜度為o 待改進 manacher方法,manacher 法將所有的字串全部變成奇數個字元。思想 回文子串一定是個中心對稱的圖形,有的對稱中心是乙個字母比如abcba,有的是對稱中心是兩個字母比如abba。所以需要分開進行 程式中會有體現 利用回文子串的這一特...