演算法解析 最長回文串(難度兩顆星)

2021-10-03 00:23:23 字數 3461 閱讀 4175

乙個回文串擁有如下特徵:無論從左向右讀,還是從右向左讀,其結果都是一樣的,比如abccba,eee就是回文串,而abcde,eefe就不是。注意,乙個空的字串也是回文串。

gildong想出了這樣乙個問題:對於給定的n個長度為m、內容各不相同字串,他想把這些字串中的某些(0個或是所有也是可以的)拼接在一起,以構成乙個回文串,要求這個回文串要盡可能長。

輸入第一行包括兩個數字nm(1≤

n≤

100,1≤

m≤50)

(1\le n \le 100, 1\le m \le 50)

(1≤n≤1

00,1

≤m≤5

0),分別是字串的個數和字串的長度。

接下來的n行,每行是乙個字串。

注意,所有的字串內容各不相同,但擁有相同的長度m

輸出第一行輸出構造的回文串長度,第二行輸出構造的回文串。

注意,構造出的最長回文串可能不唯一,這種情況下只要輸出任乙個滿足要求的即可。

例:

# input #1

3 3tab

onebat

# output #1

6tabbat

# input #2

4 2oo

oxxo

xx# output #2

6o***xo

# input #3

3 5hello

codef

orces

# output #3

0

因為所有輸入字串擁有相同的長度,所以簡化了解題難度。

從回文串的定義中可以想到,乙個回文串肯定是以中間的字元為中心兩端對稱的,那麼,如果讓我們自己隨意構造乙個回文串,應該怎麼操作?

我想可以這樣:先隨便取乙個字母,比如a,放在字串的第1個位置和倒數第1個位置,然後再取乙個字母比如b,再放到字串的第2個位置和倒數第2個位置,這樣往復下去即可:

a, b ..

.. b, a

上述構造回文數的方法是每次取乙個字元,如果每次取兩個字元呢?以ab為例,那麼就把ab放在字串的開始,然後把ab的回文串ba放在字串的末尾;再取兩個字元,比如cd,放在ab的後面,cd的回文串dc放在ba的前面,如此往復,同樣可以得到乙個回文串:

a b, c d ..

.. d c, b a

妥了,現在開始,每次取m個字元,字元的內容就是程式輸入的某個候選字串s,如果s想存在於最終生成的回文串中,需要滿足以下任乙個條件:

s的回文串存在於候選列表裡

s本身是回文串,這樣的話s可以放到最終生成的回文串的中心

因為我們想尋找乙個最長回文串,所以,s應該優先滿足條件1,否則再去滿足條件2,而且,滿足條件2的s只能保留乙個。

"""

longest palindrome

"""import sys

defget_palindrome

(s, length)

: reversed_string =

''for i in

range(0

, length)

: reversed_string += s[length-i-1]

return reversed_string

defsolve()

: string_number =

none

string_length =

none

strings =

set(

)# read input

left_strings =

none

for line in sys.stdin:

if string_number is

none

: ns = line.split(

) string_number =

int(ns[0]

) string_length =

int(ns[1]

) left_strings = string_number

else

: strings.add(line.strip())

left_strings -=

1if left_strings ==0:

break

# construct palindrome

palindrome_head =

'' palindrome_tail =

'' palindrome_pendding =

none

used_string =

set(

)for s in strings:

if s in used_string:

continue

palindrome_s = get_palindrome(s, string_length)

if s == palindrome_s:

palindrome_pendding = s

elif palindrome_s in strings:

palindrome_head += s

palindrome_tail = palindrome_s + palindrome_tail

used_string.add(palindrome_s)

result_string = palindrome_head

if palindrome_pendding is

notnone

: result_string += palindrome_pendding

result_string += palindrome_tail

print

(len

(result_string)

)print

(result_string)

if __name__ ==

'__main__'

: solve(

)

演算法 兩最長回文子串

題目 給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 複製 思路 暴力法。2層迴圈巢狀,遍歷所有子串。在判斷子串是否為回文並對比儲存最大的起止下標。通過...

最長回文串演算法

總的來說,最長回文串演算法分為以下幾種。通過遍歷整個字串來說實現對最長回文串的查詢 首先乙個字串所有子串,個數為n2個,然後逐個判斷遍歷即可,演算法複雜度o n3 如下 def is palindrome s str length len s for i in range str length 2 ...

最長回文串演算法

給定乙個字串找出最長回文字串範圍,例如abaabac,最長回文為abaaba 1 使用暴力的演算法需要o n 3 的複雜度,需要o n 2 的複雜度去運算字串所用的子串,然後使用o n 去判斷是否是回文串,從而定位最長的回文子串。cpp int lps bl char str,int len int...