📅  最后修改于: 2023-12-03 15:28:27.889000             🧑  作者: Mango
回文是一种特殊的字符串,它从前往后读和从后往前读是一样的。例如,level
、radar
和racecar
都是回文。
假设有一个由n个等长字符串组成的数组,现在允许连接这些字符串,得到一个新的字符串s。也允许重新排列s中的字符,得到一个新的字符串t。请你找到t中最长的回文子串的长度。
例如,对于输入["abcd","dcba","lls","s","sssll"], 可以将这5个字符串组合起来构成新的字符串s
,如s = "abcdllssssdcba"
, 那么重新排列s
中的字符可以得到回文串"dcabacds",那么最长的回文子串的长度为7。
我们需要找到由给定字符串组成的回文串。因为回文串是对称的,所以我们可以将每个字符串都反转然后进行比较。假设我们有两个字符串str1
和str2
,如果它们拼接成的字符串s
是回文串,那么意味着其中一个字符串需要是回文串,并且另外一个字符串的反转也需要与回文串相等。
例如,对于输入["abcd","dcba","lls","s","sssll"], 我们可以将每个字符串反转:“dcba”,“abcd”,“s”,“lls”,“llsss”。 接下来我们需要找到每个反转字符串在数组中的搭档。我们可以使用哈希表来加速查找。最后,我们将这些字符串拼接在一起,并且进行重新排列从而得到最长回文子串的长度。
def palindrome_pairs(words):
hash_table = {}
for i, word in enumerate(words):
hash_table[word[::-1]] = i
ans = 0
for i, word in enumerate(words):
for j in range(len(word) + 1):
prefix = word[:j]
suffix = word[j:]
if prefix in hash_table and i != hash_table[prefix] and suffix == suffix[::-1]:
ans = max(ans, len(word))
if j != len(word) and suffix in hash_table and i != hash_table[suffix] and prefix == prefix[::-1]:
ans = max(ans, len(word))
return ans
def longest_palindrome(words):
s = "".join(words) # 先将所有字符串拼接在一起
n = len(s)
# 对字符串进行重新排列
t = "".join(sorted(s))
# 这里分别将t分为t1, t2, t3, t4四个部分,分别反转
t1 = t[:n // 2][::-1]
t2 = t[:(n - 1) // 2][::-1]
t3 = t[n // 2:][::-1]
t4 = t[(n + 1) // 2:][::-1]
return max(palindrome_pairs(words), len(find_palindrome(t1, t2)) + len(find_palindrome(t3, t4)))
def find_palindrome(s1, s2):
"""
找到由s1和s2组成的最长回文子串
"""
n1, n2 = len(s1), len(s2)
# dp[i][j]表示s1的前i个字符和s2的前j个字符组成的最长回文子串的长度
dp = [[0] * (n2 + 1) for _ in range(n1 + 1)]
ans = 0
for i in range(1, n1 + 1):
for j in range(1, n2 + 1):
if s1[i - 1] == s2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
ans = max(ans, dp[i][j])
return ans
words = ["abcd","dcba","lls","s","sssll"]
print(longest_palindrome(words)) # 7
代码中的palindrome_pairs
函数用来找到由给定字符串组成的回文串。longest_palindrome
函数将所有字符串拼接在一起,然后进行重新排列以得到最长回文子串的长度。find_palindrome
函数用来找到由s1
和s2
组成的最长回文子串,使用动态规划实现。