Python实现最长回文字符串
题目#
最长回文字符串是一种对称的字符串,如 s = "ababd",其中"aba"或"bab"都是回文字符串。
求解思路#
最开始的思路是用类似括号匹配的放手,利用栈来做“对对消”,来判断一个字符串是不是回文字符串,但实际操作中发现 “对称轴” 元素是不确定的,前面的消除会导致后面的无法对比。
然后又被提醒到,回文对称有两种,奇数对称,如"abcba", 和偶数对称,如"abccba"。这种方式也是不一样的。
因此解决思路如下:
- 确定一个基础点作为轴点,分别按奇数策略和偶数策略(作为左边点),看是否存在回文字符串,如果两种策略都存在则返回较长的那个,如"bccca", 存在"cc"和"ccc"两种,返回"ccc“。
- 遍历这个字符串,依次作为轴点,寻找出所有的回文字符串,组成一个列表
- 遍历结果列表,返回最长的那个
代码实现#
寻找以一个索引作为轴的回文串-偶数模式,如"abba"#
from typing import Optional, List
def get_palindromic_substring_from_index_1(s: str, mid_index: int) -> Optional[str]:
"""寻找字符串s中以mid_index作为轴的对称字符串-偶数模式-作为左边点"""
if mid_index < 1:
return None
# 最大偏移量-取左右两边长度的最小值
max_offset = min([mid_index, len(s) - mid_index])
offset = 1
while offset < max_offset:
# 偶数模式,左侧偏移量-1
left, right = s[mid_index - (offset - 1)], s[mid_index + offset]
if left != right:
break # 遇到一个不对称值则跳出循环
offset += 1
# offset大于初始值则存在以该点为轴的回文字符串
if offset > 1:
offset -= 1
return s[mid_index - (offset - 1):mid_index + offset + 1]
寻找以一个索引作为轴的回文串-奇数模式,如"abcba"#
def get_palindromic_substring_from_index_2(s: str, mid_index: int) -> Optional[str]:
"""寻找字符串s中以mid_index作为轴的对称字符串-奇数模式"""
# 奇数模式
if mid_index < 1:
return None
# 最大偏移量-取左右两边长度的最小值
max_offset = min([mid_index, len(s) - mid_index])
offset = 1
while offset < max_offset:
left, right = s[mid_index - offset], s[mid_index + offset]
if left != right:
break # 遇到一个不对称值则跳出循环
offset += 1
# offset大于初始值则存在以该点为轴的回文字符串
if offset > 1:
offset -= 1
return s[mid_index - offset:mid_index + offset + 1]
综合两种模式,寻找以一个索引作为轴的较长的回文串#
def get_palindromic_substring_from_index(s: str, mid_index: int) -> Optional[str]:
"""寻找字符串s中以mid_index作为轴的对称字符-综合两种策略返回比较长的的那个"""
r1 = get_palindromic_substring_from_index_1(s, mid_index)
r2 = get_palindromic_substring_from_index_2(s, mid_index)
if r1 is None:
return r2
if r2 is None:
return r1
# 如果两种模式都存在返回比较长的那个
if len(r1) > len(r2):
return r1
return r2
寻找字符串中的所有回文串#
def get_all_palindromic_substrings(s: str) -> List[str]:
"""查找所有回文子字符串"""
results = []
for mid_index in range(1, len(s)-1):
r = get_palindromic_substring_from_index(s, mid_index)
if r is not None:
results.append(r)
return results
从所有回文串中寻找最长的那个回文串#
def get_longest_palindromic_substring(s: str) -> Optional[str]:
"""查找最长回文字符串"""
results = get_all_palindromic_substrings(s)
if len(results) == 0:
return None
# 在所有回文字符串中寻找最长的一个,如果存在长度相等的,只取其中一个
return max(results, key=len)
测试代码#
if __name__ == '__main__':
print(get_longest_palindromic_substring('ababd'))
print(get_longest_palindromic_substring('aaabacccababa'))
print(get_longest_palindromic_substring('aaabaccababa'))
注:该算法的时间复杂度为O(n^2)左右,不是最优的算法
点击查看完整代码
from typing import Optional, List
def get_palindromic_substring_from_index_1(s: str, mid_index: int) -> Optional[str]:
"""寻找字符串s中以mid_index作为轴的对称字符串-偶数模式-作为左边点"""
if mid_index < 1:
return None
# 最大偏移量-取左右两边长度的最小值
max_offset = min([mid_index, len(s) - mid_index])
offset = 1
while offset < max_offset:
# 偶数模式,左侧偏移量-1
left, right = s[mid_index - (offset - 1)], s[mid_index + offset]
if left != right:
break # 遇到一个不对称值则跳出循环
offset += 1
# offset大于初始值则存在以该点为轴的回文字符串
if offset > 1:
offset -= 1
return s[mid_index - (offset - 1):mid_index + offset + 1]
def get_palindromic_substring_from_index_2(s: str, mid_index: int) -> Optional[str]:
"""寻找字符串s中以mid_index作为轴的对称字符串-奇数模式"""
# 奇数模式
if mid_index < 1:
return None
# 最大偏移量-取左右两边长度的最小值
max_offset = min([mid_index, len(s) - mid_index])
offset = 1
while offset < max_offset:
left, right = s[mid_index - offset], s[mid_index + offset]
if left != right:
break # 遇到一个不对称值则跳出循环
offset += 1
# offset大于初始值则存在以该点为轴的回文字符串
if offset > 1:
offset -= 1
return s[mid_index - offset:mid_index + offset + 1]
def get_palindromic_substring_from_index(s: str, mid_index: int) -> Optional[str]:
"""寻找字符串s中以mid_index作为轴的对称字符-综合两种策略返回比较长的的那个"""
r1 = get_palindromic_substring_from_index_1(s, mid_index)
r2 = get_palindromic_substring_from_index_2(s, mid_index)
if r1 is None:
return r2
if r2 is None:
return r1
# 如果两种模式都存在返回比较长的那个
if len(r1) > len(r2):
return r1
return r2
def get_all_palindromic_substrings(s: str) -> List[str]:
"""查找所有回文子字符串"""
results = []
for mid_index in range(1, len(s)-1):
r = get_palindromic_substring_from_index(s, mid_index)
if r is not None:
results.append(r)
return results
def get_longest_palindromic_substring(s: str) -> Optional[str]:
"""查找最长回文字符串"""
results = get_all_palindromic_substrings(s)
if len(results) == 0:
return None
# 在所有回文字符串中寻找最长的一个,如果存在长度相等的,只取其中一个
return max(results, key=len)
if __name__ == '__main__':
print(get_longest_palindromic_substring('ababd'))
print(get_longest_palindromic_substring('aaabacccababa'))
print(get_longest_palindromic_substring('aaabaccababa'))
作者:韩志超
出处:https://www.cnblogs.com/superhin/p/18361703/python_longest_palindromic_substring
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
如有问题,请微信联系 superz-han,并发送原文链接。
标签:
Python基础面试题
, 最长回文串
/* 请我喝杯咖啡吧 */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构