python实现对求解最长回文子串的动态规划算法


Posted in Python onJune 02, 2018

基于Python实现对求解最长回文子串的动态规划算法,具体内容如下

1、题目

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

示例 1:

输入: "babad"
输出: "bab"

注意: "aba"也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

2、求解

对于暴力求解在这里就不再骜述了,着重介绍如何利用动态规划算法进行求解。

关于动态规划的含义及用法,请参考链接,这篇文章通过漫画的形式对动态规划算法进行了详细而又有风趣的介绍。值得一看。

2.1 算法一

利用常规动态规划算法,即利用表来存储每一中回文子串的可能。

基于动态规划的三要素对问题进行分析,可确定以下的状态转换方程:

python实现对求解最长回文子串的动态规划算法

其中f(i,j)表示当s[i:j]子串是否是回文串。当j-i<=1时,如果s[i] == s[j]则表示s[i:j]为回文串,及f(i,j) = true,否则f(i,j) = false。当j-i > 1时,则判断 s[i]、s[j]是否相等以及f(i+1, j-1)是否为true,即s[i+1:j-1]是否为回文串,如果为真,则f(i,j) = true

所以就需要一个n*n的二维矩阵用于存储f(i,j)的值,其中 j in range(0, k),i in range(0, j+1),之所以是j+1是因为i可以等于j。

python3代码如下:

k = len(s) # 计算字符串的长度 
 matrix = [[0 for i in range(k)] for i in range(k)] # 初始化n*n的列表 
 logestSubStr = "" # 存储最长回文子串 
 logestLen = 0 # 最长回文子串的长度 
 
  for j in range(0, k): 
   for i in range(0, j+1): 
    if j - i <= 1: 
     if s[i] == s[j]: 
      matrix[i][j] = 1   # 此时f(i,j)置为true 
      if logestLen < j - i + 1: # 将s[i:j]的长度与当前的回文子串的最长长度相比 
       logestSubStr = s[i:j+1] # 取当前的最长回文子串 
       logestLen = j - i + 1 # 当前最长回文子串的长度 
    else: 
     if s[i] == s[j] and matrix[i+1][j-1]: # 判断 
      matrix[i][j] = 1 
      if logestLen < j - i + 1: 
       logestSubStr = s[i:j+1] 
       logestLen = j - i + 1 
  return logestSubStr

 采用当前算法,时间复杂度为O(n*n),空间复杂度为O(n*n),算法平均耗时大概5~7s

下面介绍空间复杂度为O(n)的算法。

2.2 算法二

算法二是由算法一改良而来,观察算法一的执行流程如下:

python实现对求解最长回文子串的动态规划算法

当j>1时,判断f(i,j)是否为回文子串的操作只与j-1时的的操作相关,即f(i,j) = g(f(i, j-1)),其中j>1,i in range(0, j+1),所以接下来就变成求解g()函数了。   

用nlist存储j情况下所有的子串是否为回文子串的标志

用olist存储j-1情况下所有的子串是否为回文子串的标志

那么olist与nlist的关系是什么呢?

python实现对求解最长回文子串的动态规划算法

有上图可知,nlist[i] = g(olist[i+1])

新的算法如下:

k = len(s) 
 olist = [0] * k # 申请长度为n的列表,并初始化 
nList = [0] * k # 同上 
logestSubStr = "" 
 logestLen = 0 
 
  for j in range(0, k): 
   for i in range(0, j + 1): 
    if j - i <= 1: 
     if s[i] == s[j]: 
      nList[i] = 1 # 当 j 时,第 i 个子串为回文子串 
      len_t = j - i + 1 
      if logestLen < len_t: # 判断长度 
       logestSubStr = s[i:j + 1] 
       logestLen = len_t 
    else: 
     if s[i] == s[j] and olist[i+1]: # 当j-i>1时,判断s[i]是否等于s[j],并判断当j-1时,第i+1个子串是否为回文子串 
      nList[i] = 1 # 当 j 时,第 i 个子串为回文子串 
      len_t = j - i + 1 
      if logestLen < len_t: 
       logestSubStr = s[i:j + 1] 
       logestLen = len_t 
   olist = nList  # 覆盖旧的列表 
   nList = [0] * k # 新的列表清空 
  return logestSubStr

 这样新算法的空间复杂度就为O(2n),即O(n)。算法平均耗时3s左右,而且该算法更符合动态规划的原理。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中的对象拷贝示例 python引用传递
Jan 23 Python
python列表去重的二种方法
Feb 14 Python
Python中字典映射类型的学习教程
Aug 20 Python
Python入门_浅谈数据结构的4种基本类型
May 16 Python
利用python求相邻数的方法示例
Aug 18 Python
Python实现重建二叉树的三种方法详解
Jun 23 Python
Python完成哈夫曼树编码过程及原理详解
Jul 29 Python
django迁移数据库错误问题解决
Jul 29 Python
python 爬虫 实现增量去重和定时爬取实例
Feb 28 Python
Python的PIL库中getpixel方法的使用
Apr 09 Python
Pytorch数据拼接与拆分操作实现图解
Apr 30 Python
Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)
Dec 07 Python
Python 网络爬虫--关于简单的模拟登录实例讲解
Jun 01 #Python
用Python一键搭建Http服务器的方法
Jun 01 #Python
python 编写简单网页服务器的实例
Jun 01 #Python
Django中间件实现拦截器的方法
Jun 01 #Python
Python使用add_subplot与subplot画子图操作示例
Jun 01 #Python
详解Python如何生成词云的方法
Jun 01 #Python
Python实现的个人所得税计算器示例
Jun 01 #Python
You might like
PHP中的串行化变量和序列化对象
2006/09/05 PHP
PHP入门学习的几个不错的实例代码
2008/07/13 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
2017/12/25 PHP
在php的yii2框架中整合hbase库的方法
2018/09/20 PHP
简单实用的全选反选按钮例子
2013/10/18 Javascript
js实现动态改变字体大小代码
2014/01/02 Javascript
JavaScript生成随机字符串的方法
2015/03/19 Javascript
JS或jQuery获取ASP.NET服务器控件ID的方法
2015/06/08 Javascript
javascript日期格式化方法汇总
2015/10/04 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
JavaScript判断图片是否已经加载完毕的方法汇总
2016/02/05 Javascript
js实现tab切换效果
2017/02/16 Javascript
vue2.0 中#$emit,$on的使用详解
2017/06/07 Javascript
webpack构建vue项目的详细教程(配置篇)
2017/07/17 Javascript
Angular4如何自定义首屏的加载动画详解
2017/07/26 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
解决vue的 v-for 循环中图片加载路径问题
2018/09/03 Javascript
详解微信小程序支付流程与梳理
2019/07/16 Javascript
JS事件流与事件处理程序实例分析
2019/08/16 Javascript
JavaScript 获取滚动条位置并将页面滑动到锚点
2021/02/08 Javascript
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
[01:33:07]VGJ.T vs Newbee Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
python多线程编程中的join函数使用心得
2014/09/02 Python
python运行时间的几种方法
2016/06/17 Python
python matlibplot绘制多条曲线图
2021/02/19 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
2018/12/05 Python
pyqt5 删除layout中的所有widget方法
2019/06/25 Python
Python搭建HTTP服务过程图解
2019/12/14 Python
CSS+jQuery+PHP+MySQL实现的在线答题功能
2015/04/25 HTML / CSS
美国最大的船只买卖在线市场:Boat Trader
2018/08/04 全球购物
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
教育科学研究生自荐信
2013/10/09 职场文书
2015年度村委会工作总结
2015/04/29 职场文书
运动会3000米加油稿
2015/07/21 职场文书
2016年大学生寒假社会实践心得体会
2015/10/09 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书