文章目录
- 回文字符串
- 如何判断是回文字符串
- 求解字符串的最大回文子串
- 暴力求解
- 中心扩展(比较优的方式)
- 两种方式性能对比
回文字符串
正读、反读都是同一个字符串本身,这样的字符串就是回文字符串。
如 abccba 是回文字符串;
而 abcd 却不是回文字符串
如何判断是回文字符串
字符串的
第一个位置与最后一个位置字符相同;
第二个位置与倒数第二个位置字符相同;
依次类推…
满足这样的要求的就是回文字符串。
代码实现,判断是否为回文字符串
# __author__ = "laufing"
def is_palindrome(target_s: str) -> bool:
""" 是否回文字符串 两边对称 """
if len(target_s) < 2:
return True
n = len(target_s)
for i in range(n//2):
# 取第一个字符 与 最后一个字符比较
if target_s[i] == target_s[n - i - 1]:
continue
else:
return False
else:
return True
if __name__ == '__main__':
s = "abccba"
print(is_palindrome(s))
求解字符串的最大回文子串
给定一个字符串,求解其最大的回文子串。
例子1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
例子2:
输入: “abaelele”
输出: “elele”
暴力求解
暴力求解思路:
列出目标字符串的所有的子串,根据长度从大到小,依次循环判断每个子串是否为回文字符串,找到则停止。
# 暴力求解
def find_max_palindrome(target_s: str) -> str:
if len(target_s) < 2:
return target_s
result = ""
n = len(target_s)
for i in range(n, 0, -1):
for j in range(n + 1 - i):
sub_str = target_s[j:j+i]
if is_palindrome(sub_str):
result = sub_str
return result
# 时间复杂度O(n^3) 空间复杂度O(1)
中心扩展(比较优的方式)
思路:
从左到右依次遍历字符串的每个字符,每个字符向两边扩展,只要最内部不是回文,则后续的扩展也不可能是回文;继续遍历下一个字符。
# 中心扩展法
def center_expand(target_s: str) -> str:
if len(target_s) < 2:
return target_s
n = len(target_s)
result = ""
for i in range(n):
# 奇数回文
temp1 = do_expand(target_s, i, i)
# 偶数回文
temp2 = do_expand(target_s, i, i + 1)
if len(temp1) > len(result):
result = temp1
if len(temp2) > len(result):
result = temp2
return result
# 核心部分
def do_expand(target_s, left, right):
""" 两边扩展: left 左边索引; right右边索引 """
while left >= 0 and right < len(target_s) and target_s[left] == target_s[right]:
left -= 1
right += 1
return target_s[left + 1 : right]
两种方式性能对比
# timeit测试性能
from timeit import Timer
# s = "abadcaacdele"
s = "abaelele"
timer1 = Timer("find_max_palindrome(s)", globals=globals()) # 测试是在另一个位置,
# 所以查找函数及参数需要指定globals()
timer2 = Timer("center_expand(s)", "from __main__ import center_expand, s") # 也可导入
t1 = timer1.repeat(5, 10000) # 重复测试5次(timeit),每次执行1000次的时间
t2 = timer2.repeat(5, 10000)
print("暴力求解性能:", t1)
print("中心扩展性能:", t2)
此时暴力求解的性能还略优于中心扩展法,这个是与最大回文子串的长度有关系的,当最大回文子串的长度与目标字符串的总长度相差大的时候,暴力求解就的劣势就会显示出来。
如求解 s = "ipqabadcaacdeleffggklmen"这个字符串的最大回文子串,性能对比如下:
此时,暴力求解占用时间明显增多,中心扩展法性能高出很多。
总结:中心扩展法是比较优的解法。