Python实现常见的回文字符串算法

博客主要围绕回文问题展开,利用Python实现多种算法。包括判断回文的方法,求解最长回文子串的暴力破解、动态规划和Manacher算法,最长回文前缀借助KMP算法,添加字符生成最短回文字符串,以及用动态规划法求最长回文子序列,还分析了各算法复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

回文

 

利用python 自带的翻转 函数reversed()

自己实现


最长的回文子串

暴力破解

暴力破解,枚举所有的子串,对每个子串判断是否为回文, 时间复杂度为 O(n^3)

动态规划

时间复杂度为 O(n^2), 空间复杂度为 O(n^2)

Manacher 算法

Manacher 算法首先对字符串做一个预处理,使得所有的串都是奇数长度, 插入的是同样的符号且符号不存在与原串中,串的回文性不受影响

我们把回文串中最右位置与其对称轴的距离称为回文半径,Manacher 算法定义了一个回文半径数组 RL,RL[i]表示以第 i 个字符为对称轴的回文半径,对于上面得到的插入分隔符的串来说,我们可以得到 RL数组

我们还求了 RL[i] - 1: 我们发现RL[i] -1 正好是初始字符串中以位置i 为对称轴的最长回文长度

所以下面就是重点如何求得 RL 数组了

下面是算法实现

空间复杂度:借助了一个辅助数组,空间复杂度为 O(n)

时间复杂度:尽管内层存在循环,但是内层循环只对尚未匹配的部分进行,对于每一个字符来说,只会进行一次,所以时间复杂度是 O(n)

最长回文前缀

所谓前缀,就是以第一个字符开始

下面的最长回文前缀

将原串逆转,那么问题就转变为求原串的前缀和逆串后缀相等且长度最大的值, 这个问题其实就是 KMP 算法中的 next 数组的求解了

具体求解: 将原串逆转并拼接到原串中, 以’#’ 分隔原串和逆转避免内部字符串干扰。


添加字符生成最短回文字符串

这道题其实跟上面基本是一样的,

实例:

我们先求字符串的最长回文前缀, 然后剩余的字符串逆转并拼接到字符串的头部即是问题所求


最长回文子序列

动态规划法

dp[i][j] 表示子序列 s[i..j] 中存在的最长回文子序列长度

初始化dp[i][i] = 1

当 s[i] == s[j] 为 true 时,dp[i][j] = dp[i+1][j - 1] + 2

当 s[i] == s[j] 为 false 时,dp[i][j] = max(dp[i+1][j], dp[i][j - 1])

时间复杂度为 O(n^2), 空间复杂度为 O(n^2)

### Python 实现回文字符串算法示例代码 以下是一个基于 Python回文字符串检测算法实现。该算法不仅能够判断一个字符串是否为回文,还提供了查找最长回文子串的功能[^1]。 ```python def is_palindrome(s: str) -> bool: """ 判断一个字符串是否为回文。 :param s: 输入的字符串 :return: 如果是回文 True,否则返 False """ return s == s[::-1] def longest_palindrome(s: str) -> str: """ 查找字符串中的最长回文子串。 :param s: 输入的字符串 :return: 最长的回文子串 """ if not s or len(s) < 1: return "" start, end = 0, 0 def expand_around_center(left: int, right: int) -> int: """ 从中心扩展以找到最长回文子串的边界。 :param left: 左边界索引 :param right: 右边界索引 :return: 当前中心的最大回文长度 """ while left >= 0 and right < len(s) and s[left] == s[right]: left -= 1 right += 1 return right - left - 1 for i in range(len(s)): len1 = expand_around_center(i, i) # 奇数长度回文 len2 = expand_around_center(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] ``` #### 示例运行 以下是上述代码的使用示例: ```python # 测试回文检测函数 test_str = "level" print(f"字符串 '{test_str}' 是否为回文: {is_palindrome(test_str)}") # 输出: True # 测试最长回文子串查找函数 input_str = "babad" result = longest_palindrome(input_str) print(f"字符串 '{input_str}' 的最长回文子串为: '{result}'") # 输出: 'bab' 或 'aba' ``` 以上代码中,`is_palindrome` 函数通过简单的字符串反转比较来判断是否为回文[^2]。而 `longest_palindrome` 函数则采用“中心扩展法”来查找最长回文子串,这种方法的时间复杂度为 \(O(n^2)\),适合处理长度不超过 1000 的字符串[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值