最长回文字符串
1.什么是回文字符串?
回文字符串是指正向和反向读取都相同的字符串。例如,"level"和"madam"都是回文字符串。
2.问题描述
给定一个字符串,我们需要找到其中最长的回文字符串。
3.解决方法
3.1 暴力法
暴力法是一种最简单的方法,它检查字符串的所有可能子字符串,并找到其中的最长回文字符串。算法的时间复杂度为O(n^3)。
下面是使用Python实现的暴力法代码示例:
def is_palindrome(s):
return s == s[::-1]
def longest_palindrome(s):
n = len(s)
max_len = 0
max_str = ""
for i in range(n):
for j in range(i+1, n+1):
if is_palindrome(s[i:j]) and j-i > max_len:
max_len = j-i
max_str = s[i:j]
return max_str
3.2 动态规划法
动态规划法通过使用子问题的解来构建更大问题的解。对于回文字符串,我们可以使用一个二维数组来保存子问题的解。如果s[i:j]是回文字符串,那么s[i+1:j-1]也是回文字符串,并且s[i] == s[j]。通过计算每个子问题的解,我们可以构建更长的回文字符串。算法的时间复杂度为O(n^2)。
下面是使用Python实现的动态规划法代码示例:
def longest_palindrome(s):
n = len(s)
dp = [[False] * n for _ in range(n)]
max_len = 0
max_str = ""
# 单个字符都是回文字符串
for i in range(n):
dp[i][i] = True
max_len = 1
max_str = s[i]
# 计算长度为2的回文字符串
for i in range(n-1):
if s[i] == s[i+1]:
dp[i][i+1] = True
max_len = 2
max_str = s[i:i+2]
# 计算长度大于2的回文字符串
for length in range(3, n+1):
for i in range(n-length+1):
j = i + length - 1
if s[i] == s[j] and dp[i+1][j-1]:
dp[i][j] = True
if length > max_len:
max_len = length
max_str = s[i:j+1]
return max_str
3.3 中心扩展法
中心扩展法是一种更为高效的方法。对于每个字符,我们将其作为中心字符,并向左右两边扩展,直到不满足回文条件为止。算法的时间复杂度为O(n^2)。
下面是使用Python实现的中心扩展法代码示例:
def expand_around_center(s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return right - left - 1
def longest_palindrome(s):
if s == "":
return s
start, end = 0, 0
for i in range(len(s)):
len1 = expand_around_center(s, i, i)
len2 = expand_around_center(s, i, i+1)
max_len = max(len1, len2)
if max_len > end - start:
start = i - (max_len - 1) // 2
end = i + max_len // 2
return s[start:end+1]
4.性能比较
下表比较了上述三种方法的时间复杂度和空间复杂度。
方法 | 时间复杂度 | 空间复杂度 |
---|---|---|
暴力法 | O(n^3) | O(1) |
动态规划法 | O(n^2) | O(n^2) |
中心扩展法 | O(n^2) | O(1) |
从上表中可以看出,中心扩展法是最优的方法,它具有较低的时间复杂度和空间复杂度。
5.总结
本文介