日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python programming training(一):最大回文子字符串

發(fā)布時間:2025/4/5 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python programming training(一):最大回文子字符串 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概念

回文字符串是指一個字符串從左到右與從右到左遍歷得到的序列是相同的。例如“abcba“就是回文字符串,而"abcab"則不是回文字符串。

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

方法

求回文字符串的方法

目錄

概念

方法

1. 暴力枚舉法

2. 中心搜索法

3. 中心擴(kuò)展法

github地址


分析與解答:

最容易想到的方法為遍歷字符串所有可能的子串(暴力法),判斷其是否為回文字符串看,然后找出最長的回文字串。但是當(dāng)字符串很長的時候,這種方法的效率是非常低下的,因此這種方法不可取。

給定字符串"",假設(shè)p(i, j)=1表示“”是回文字符串;P(i, j)=0表示“”不是回文字符串;

如果:那么P(i, i+1)=1,否則P(i, i+1) =0.

如過:那么P(i+1, j+1)=p(i, j).?
————————————————
版權(quán)聲明:本文為CSDN博主「灬蠟筆灬」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_42013574/article/details/88825930

1. 暴力枚舉法

從長到短遍歷,找到所有子串,判斷每一個子串是否是回文.即a==a[::-1]

參考:https://blog.csdn.net/wangweimic/article/details/93977486

# 從長到短,依次遍歷判斷所有的子字符串,st= st[::-1] def get_reverstring(string):substring_length = len(string)while substring_length > 0:for i in range(len(string) - substring_length + 1):# 因為從長到短,需要遍歷[0:17];[0:16]、[1:17]...,所以需要另一個循環(huán)在每次更新要檢測的子字符串長度時,重置上面的range()函數(shù).# i從一開始的0到0,1到0,1,2,是在被減去的數(shù)值范圍內(nèi)循環(huán)遍歷# 另一方面,依次遞減需要檢測的子字符串的長度,直到子字符串為空,長度為0,這是一個典型的while循環(huán)呀。# 最后需要測試,檢驗代碼是否正常運行temp = string[i: i + substring_length]if temp == temp[::-1]:return tempsubstring_length -= 1print get_reverstring("abcdcbadegtefetge")

2. 中心搜索法

選取一個中心點index,按偶數(shù)和奇數(shù)兩種情況進(jìn)行遍歷尋找,并將獲得的子字符串進(jìn)行比較,返回最大子字符串。

參考:https://blog.csdn.net/weixin_41863544/article/details/110493234

class Solution(object):def center(self, left, right, s):step = []# 如果是奇數(shù)字符串if left == right:k = 1while left - k >= 0 and left + k < len(s):if s[left - k] == s[right + k]:step = s[left - k: right + k + 1]k += 1else:break# 如果是偶數(shù)字符串if left + 1 == right:k = 0while left - k >= 0 and right + k < len(s):if s[left - k] == s[right + k]:step = s[left - k: right + k + 1]k += 1else:breakreturn stepdef longestPalindrome(self, s):""":type s: str:rtype: str"""l = []for i in range(0, len(s) - 1):# 假設(shè)i為奇數(shù)字符串中心的情況,進(jìn)行回文字符串判斷step1 = self.center(i, i, s)# 假設(shè)i為偶數(shù)字符串中心的情況,進(jìn)行回文字符串判斷step2 = self.center(i, i + 1, s)if len(l) < max(len(step1), len(step2)):if len(step1) > len(step2):l = step1else:l = step2if l == []:return s[0]return ls = "cdeffeba" o = Solution() print(o.longestPalindrome(s)) # leetcode submit region end(Prohibit modification and deletion) # 可以將自定義的python函數(shù)封裝成一個類class Solution(object),通過創(chuàng)建對象o = class_name(),對象調(diào)用類內(nèi)創(chuàng)建的函數(shù)獲得運行結(jié)果o.longestPalindrome(s)

3. 中心擴(kuò)展法

枚舉實現(xiàn)的耗時是我們無法忍受的。那么有沒有高效查找回文子串的方法呢?答案當(dāng)然是肯定的,那就是中心擴(kuò)展法,選擇一個元素作為中心,然后向外發(fā)散的尋找以該元素為圓心的最大回文子串。但是又出現(xiàn)了新的問題,回文子串的長度即可能是基數(shù),也可能好是偶數(shù),對于長度為偶數(shù)的回文子串來說是不存在中心元素的。那有什么方法解決中心擴(kuò)展法中的偶數(shù)奇數(shù)、有中心無中心問題呢?

那是否有一種辦法能將奇偶長度的子串歸為一類,統(tǒng)一使用中心擴(kuò)展法呢?它就是manacher算法,在原字符串中插入特殊字符,例如插入#后原字符串變成'#3#5#5#3#4#3#2#1#'。這樣無論原字符串長度是奇數(shù)還是偶數(shù),擴(kuò)展后的字符串長度都是奇數(shù),所以只需要以index為中心向兩邊擴(kuò)展判斷即可。

現(xiàn)在我們對新字符串使用中心擴(kuò)展發(fā)即可,中心擴(kuò)展法得到的不含中心點的半徑長度就是子串的長度

參考:https://www.cnblogs.com/baiyb/p/8326216.html

  • 中心擴(kuò)展法~優(yōu)化前
def get_max_substr(string):str_list = [s for s in string]center_string = '#' + '#'.join(str_list) + '#'# 以需要判斷的字符串中心為循環(huán)條件,每次循環(huán)操作對象:全部的數(shù)組 --> 雙循環(huán)max_range = 0max_substr = ''for index in range(0, len(center_string)):temp_range = 0# 以index為中心擴(kuò)展的字符串半徑,最長是index,e.g. index =0, max_radius = 0; index = 1, max_radius = 1for r in range(1, index + 1):if index - r >= 0 and index + r <= len(center_string) - 1:print center_string[index - r], center_string[index + r]if center_string[index - r] == center_string[index + r]:temp_range = relse:breakelse:break# substr, substr_length = get_str_length(center_string, index)if temp_range > max_range:max_range = temp_rangemax_substr = center_string[index - max_range : index + max_range + 1].replace('#', '')return max_range, max_substrif __name__ == "__main__":string = "ecaacd"max_range, max_substr = get_max_substr(string)print max_range, max_substr
  • 中心擴(kuò)展法優(yōu)化后

功能已經(jīng)實現(xiàn)了,經(jīng)過測試也沒有bug,但是我們靜下心來想一想,目前的解法是否還有優(yōu)化空間呢?根據(jù)目前的解法,如果某個index3中心的最長回文子串長度比max_length要小,我們不必更新max_length。換句話說,我們計算以index3為中心的最長回文字串長度是做了無用功。

==> 優(yōu)化:在遍歷一個新的元素時,我們要優(yōu)先判斷它有沒有潛質(zhì)能超越max_length,如果不能超過,就繼續(xù)遍歷下一個元素。

def get_max_substr(string):str_list = [s for s in string]center_string = '#' + '#'.join(str_list) + '#'# 以需要判斷的字符串中心為循環(huán)條件,每次循環(huán)操作對象:全部的數(shù)組 --> 雙循環(huán)max_range = 0max_substr = ''for index in range(0, len(center_string)):temp_range = 0# 以index為中心擴(kuò)展的字符串半徑,最長是index,e.g. index =0, max_radius = 0; index = 1, max_radius = 1for r in range(max_range + 1, index + 1):# 以index為中心,r為半徑的子字符串長度是否在整體字符串范圍內(nèi)-->優(yōu)化:我覺得直接判斷index中心有沒有超過max_range的潛質(zhì)if index - max(max_range, r) >= 0 and index + max(max_range, r) <= len(center_string) - 1:# 取子字符串時,注意排序str_l = center_string[index - 1:index - max_range - 1: -1]str_r = center_string[index + 1: index + max_range + 1]# print str_l, str_rif str_l == str_r:if center_string[index - r] == center_string[index + r]:temp_range = relse:breakelse:breakelse:breakif temp_range > max_range:max_range = temp_rangemax_substr = center_string[index - max_range: index + max_range + 1].replace('#', '')return max_range, max_substrif __name__ == "__main__":string = "ecaac"max_range, max_substr = get_max_substr(string)print max_range, max_substr

github地址

yuyongsheng1990:https://github.com/yuyongsheng1990/python_training/tree/master/training_001_Longest_Palindrome_String

總結(jié)

以上是生活随笔為你收集整理的python programming training(一):最大回文子字符串的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。