概念

回文字符串是指一个字符串从左到右与从右到左遍历得到的序列是相同的。例如“abcba“就是回文字符串,而"abcab"则不是回文字符串。

回文字符串给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最长回文子串是'3553',所以返回4。

方法

求回文字符串的方法

目录

概念

方法

1. 暴力枚举法

2. 中心搜索法

3. 中心扩展法

github地址


分析与解答:

最容易想到的方法为遍历字符串所有可能的子串(暴力法),判断其是否为回文字符串看,然后找出最长的回文字串。但是当字符串很长的时候,这种方法的效率是非常低下的,因此这种方法不可取。

给定字符串"",假设p(i, j)=1表示“”是回文字符串;P(i, j)=0表示“”不是回文字符串;

如果:那么P(i, i+1)=1,否则P(i, i+1) =0.

如过:那么P(i+1, j+1)=p(i, j). 
————————————————
版权声明:本文为CSDN博主「灬蜡笔灬」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42013574/article/details/88825930

1. 暴力枚举法

从长到短遍历,找到所有子串,判断每一个子串是否是回文.即a==a[::-1]

参考:https://blog.csdn.net/wangweimic/article/details/93977486

# 从长到短,依次遍历判断所有的子字符串,st= st[::-1]
def get_reverstring(string):substring_length = len(string)while substring_length > 0:for i in range(len(string) - substring_length + 1):# 因为从长到短,需要遍历[0:17];[0:16]、[1:17]...,所以需要另一个循环在每次更新要检测的子字符串长度时,重置上面的range()函数.# i从一开始的0到0,1到0,1,2,是在被减去的数值范围内循环遍历# 另一方面,依次递减需要检测的子字符串的长度,直到子字符串为空,长度为0,这是一个典型的while循环呀。# 最后需要测试,检验代码是否正常运行temp = string[i: i + substring_length]if temp == temp[::-1]:return tempsubstring_length -= 1print get_reverstring("abcdcbadegtefetge")

2. 中心搜索法

选取一个中心点index,按偶数和奇数两种情况进行遍历寻找,并将获得的子字符串进行比较,返回最大子字符串。

参考:https://blog.csdn.net/weixin_41863544/article/details/110493234

class Solution(object):def center(self, left, right, s):step = []# 如果是奇数字符串if left == right:k = 1while left - k >= 0 and left + k < len(s):if s[left - k] == s[right + k]:step = s[left - k: right + k + 1]k += 1else:break# 如果是偶数字符串if left + 1 == right:k = 0while left - k >= 0 and right + k < len(s):if s[left - k] == s[right + k]:step = s[left - k: right + k + 1]k += 1else:breakreturn stepdef longestPalindrome(self, s):""":type s: str:rtype: str"""l = []for i in range(0, len(s) - 1):# 假设i为奇数字符串中心的情况,进行回文字符串判断step1 = self.center(i, i, s)# 假设i为偶数字符串中心的情况,进行回文字符串判断step2 = self.center(i, i + 1, s)if len(l) < max(len(step1), len(step2)):if len(step1) > len(step2):l = step1else:l = step2if l == []:return s[0]return ls = "cdeffeba"
o = Solution()
print(o.longestPalindrome(s))
# leetcode submit region end(Prohibit modification and deletion)
#  可以将自定义的python函数封装成一个类class Solution(object),通过创建对象o = class_name(),对象调用类内创建的函数获得运行结果o.longestPalindrome(s)

3. 中心扩展法

枚举实现的耗时是我们无法忍受的。那么有没有高效查找回文子串的方法呢?答案当然是肯定的,那就是中心扩展法,选择一个元素作为中心,然后向外发散的寻找以该元素为圆心的最大回文子串。但是又出现了新的问题,回文子串的长度即可能是基数,也可能好是偶数,对于长度为偶数的回文子串来说是不存在中心元素的。那有什么方法解决中心扩展法中的偶数奇数、有中心无中心问题呢?

那是否有一种办法能将奇偶长度的子串归为一类,统一使用中心扩展法呢?它就是manacher算法,在原字符串中插入特殊字符,例如插入#后原字符串变成'#3#5#5#3#4#3#2#1#'。这样无论原字符串长度是奇数还是偶数,扩展后的字符串长度都是奇数,所以只需要以index为中心向两边扩展判断即可。

现在我们对新字符串使用中心扩展发即可,中心扩展法得到的不含中心点的半径长度就是子串的长度。

参考:https://www.cnblogs.com/baiyb/p/8326216.html

  • 中心扩展法~优化前
def get_max_substr(string):str_list = [s for s in string]center_string = '#' + '#'.join(str_list) + '#'# 以需要判断的字符串中心为循环条件,每次循环操作对象:全部的数组 --> 双循环max_range = 0max_substr = ''for index in range(0, len(center_string)):temp_range = 0# 以index为中心扩展的字符串半径,最长是index,e.g. index =0, max_radius = 0; index = 1, max_radius = 1for r in range(1, index + 1):if index - r >= 0 and index + r <= len(center_string) - 1:print center_string[index - r], center_string[index + r]if center_string[index - r] == center_string[index + r]:temp_range = relse:breakelse:break# substr, substr_length = get_str_length(center_string, index)if temp_range > max_range:max_range = temp_rangemax_substr = center_string[index - max_range : index + max_range + 1].replace('#', '')return max_range, max_substrif __name__ == "__main__":string = "ecaacd"max_range, max_substr = get_max_substr(string)print max_range, max_substr
  • 中心扩展法优化后

功能已经实现了,经过测试也没有bug,但是我们静下心来想一想,目前的解法是否还有优化空间呢?根据目前的解法,如果某个index3中心的最长回文子串长度比max_length要小,我们不必更新max_length。换句话说,我们计算以index3为中心的最长回文字串长度是做了无用功。

==> 优化:在遍历一个新的元素时,我们要优先判断它有没有潜质能超越max_length,如果不能超过,就继续遍历下一个元素。

def get_max_substr(string):str_list = [s for s in string]center_string = '#' + '#'.join(str_list) + '#'# 以需要判断的字符串中心为循环条件,每次循环操作对象:全部的数组 --> 双循环max_range = 0max_substr = ''for index in range(0, len(center_string)):temp_range = 0# 以index为中心扩展的字符串半径,最长是index,e.g. index =0, max_radius = 0; index = 1, max_radius = 1for r in range(max_range + 1, index + 1):# 以index为中心,r为半径的子字符串长度是否在整体字符串范围内-->优化:我觉得直接判断index中心有没有超过max_range的潜质if index - max(max_range, r) >= 0 and index + max(max_range, r) <= len(center_string) - 1:# 取子字符串时,注意排序str_l = center_string[index - 1:index - max_range - 1: -1]str_r = center_string[index + 1: index + max_range + 1]# print str_l, str_rif str_l == str_r:if center_string[index - r] == center_string[index + r]:temp_range = relse:breakelse:breakelse:breakif temp_range > max_range:max_range = temp_rangemax_substr = center_string[index - max_range: index + max_range + 1].replace('#', '')return max_range, max_substrif __name__ == "__main__":string = "ecaac"max_range, max_substr = get_max_substr(string)print max_range, max_substr

github地址

yuyongsheng1990:https://github.com/yuyongsheng1990/python_training/tree/master/training_001_Longest_Palindrome_String

python programming training(一):最大回文子字符串相关推荐

  1. Java字符串中最长回文子字符串

    Longest palindrome substring in a string is a very common java interview question. To find out the l ...

  2. Java实现 LeetCode 730 统计不同回文子字符串(动态规划)

    730. 统计不同回文子字符串 给定一个字符串 S,找出 S 中不同的非空回文子序列个数,并返回该数字与 10^9 + 7 的模. 通过从 S 中删除 0 个或多个字符来获得子字符序列. 如果一个字符 ...

  3. manecher算法 最长回文子字符串

    还没放假的时候就知道有这么一种算法,之前看了一下以为很难就没好好学,今天早上用心看了一下,发现其实很简单.学什么东西都应该静下心来好好理解好好学,才能保证高效率! 我主要是看这篇博客学的马拉车,我觉得 ...

  4. 快手腾讯校招笔试题最长回文子序

    腾讯2017 给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串.如何删除才能使得回文串最长呢? 输出需要删除的字符个数. 输入描述: 输入数据有多组,每组包含一个字符串s,且保证:1 ...

  5. LintCode Python 简单级题目 491.回文数

    原题描述: 判断一个正整数是不是回文数. 回文数的定义是,将这个数反转之后,得到的数仍然是同一个数. 注意事项 给的数一定保证是32位正整数,但是反转之后的数就未必了. 您在真实的面试中是否遇到过这个 ...

  6. Python双端队列之回文词判定

    双端队列(Deque):由一系列有序的元素组织而成,元素可以从队首或队尾插入.删除. Python自带Deque模块,使用时需引用from collections import deque. 回文词: ...

  7. 【Python蓝桥杯】特殊回文数 123321是一个非常特殊的数,它从左边读和从右边读是一样的。输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。

    最近在刷蓝桥杯题目,按题目做一下笔记整理,顺便分享交流一下,有更好的解决方案欢迎大家共同提出探讨,以下源代码为系统提交满分答案 特殊回文数 问题描述 资源限制 Python时间限制:5.0s. 问题描 ...

  8. 【100%通过率】华为OD机试真题 Python 实现【最长回文字符串】【2023 Q1 | 100分】

            所有题目均有五种语言实现.C实现目录.C++ 实现目录.Python实现目录.Java实现目录.JavaScript实现目录 题目 如果一个字符串正读和反渎都一样(大小写敏感) ,则称 ...

  9. 【Leetcode刷题Python】516. 最长回文子序列

    1 题目 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度. 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列. 示例 1: 输入:s = &q ...

最新文章

  1. android 自定义弹窗,Android自定义弹窗
  2. Kaggle入门,看这一篇就够了
  3. java执行cmd命令,返回结果中文乱码问题解决
  4. 知识点2-对二进制的运用
  5. android 编写系统应用,Android应用快速开发系统设计与实现
  6. UA OPTI501 电磁波 Lorentz Oscillator Model 3 相速度与群速度
  7. Mycat安全权限配置user_配置mycat用户只读数据---MyCat分布式数据库集群架构工作笔记0031
  8. 表达式 jsp_[JSTL表达式] -JSTL中的所有,都在这
  9. JQuery:视频+实战总结
  10. java2048设计说明,Html5中的本地存储设计理念
  11. openCV+ASM+LBP+Gabor实现人脸识别(GT人脸库)
  12. windows系统中Dotnet core runtime 安装后,无法启动次程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll的解决方法...
  13. 挑战程序设计竞赛 — 知识总结
  14. 负载均衡(Load Balance)
  15. 如何判断BIOS设置是否开启CPU虚拟化功能?
  16. 请将磁盘插入‘‘U盘(F:)‘‘的解决方法
  17. matlab如何igbt开关频率,IGBT的开关时间说明
  18. iPhone上Siri无法正常回应如何解决?
  19. ROC曲线与AUC值
  20. terraform登录ec2实例

热门文章

  1. CISCO NAT 配置
  2. codeforces 665B Shopping
  3. 统一沟通-技巧-12-Lync-CX600-3000-5000-配置-internet
  4. 中小企业ERP快速实施的八大准则
  5. Kattis-What does the fox say 字符串处理+STL
  6. ambari hive mysql_ambari方式安装hadoop的hive组件遇到的问题
  7. u盘排序软件_总有一款U盘适合你
  8. android view强制重绘_android view 相关方法 layout draw 布局 重绘 | 学步园
  9. 框架 路由地址_Django框架的使用
  10. 科幻作文计算机,种子科幻作文