516、最长回文子序列

news/2024/9/23 4:19:12/

                                                                                                                                            点击此处返回总目录

 

【题目】

 

注意,子序列跟子串是不一样的。子序列是从字符串中取出元素,相对顺序不变,但是可以不挨着。子串肯定是截取一段。

 

 

【方法一:记忆化搜索】

假设fun(char[] S , int i , int j) 返回的是串S[i...j]的最长回文子序列。

则如果S[i]==S[j] , 则:fun(S, i , j) = 2+fun(S , i+1 , j-1)

如果不等,则,fun(S , i , j) = max{ fun(S, i+1 , j) ,  fun(S , i , j-1)}

 

递归写法如下:

 

很显然,会超时:

因为计算了很多遍重复的。

 

 

因此,需要进行改进:将中间结果进行保存。下次计算的时候就不需要重复计算了。这就是记忆化搜索的方法。

 

 

代码:

 

结果:

 

 

 

【方法二:动态规划】

设dp[i][j]为从i到j的字符串,回文子序列的最大长度。

 

 

 

 

代码:

 

 

为什么这么写呢?

首先要心中有这个图。

                                            

                                             

主对角线是我们自己填进去的。dp[i][i]=1。其他元素我们是用dp[][]式子求的。并没有把次对角线和其他元素分开计算。是因为能够统一写。

首先看次对角线的元素。比如dp[2][3]。如果S[2]==S[3],则dp[2][3]=dp[3][2]+2。而dp[3][2]虽然没有求,但是是默认值0,这样dp[2][3]=2。如果S[2]!=S[3],则dp[2][3]=max(dp[3][3], dp[2][2])=1。都是对的。

对于其他元素dp[i][j]。如果S[i]==S[j],则dp[i][j]=2+dp[i+1][j-1],用到了那个左小角的元素。如果S[i]!=S[j],则dp[i][j]=max(dp[i][j-1],dp[i+1][j]),用到了左边和右边的两个元素。

按照我们先下后上,先左后右的顺序,左下、下、左的元素都求出来了。所以肯定能求出dp[i][j]。

                                                 

 

 

结果:

 

时间复杂度:o(n^2)

 

虽然只跑出了32ms,但是看17ms的答案也是这么写的。
 

 

注:

我在看相关的书和博客的时候,有下面一些叫法,感觉都一样:

记忆化搜索 =   记忆递归型的动态规划    =  记忆化递归

动规            =  递推型动态规划

 

叫法就不纠结了。

 

 

 

 

 


http://www.ppmy.cn/news/387592.html

相关文章

【JavaSE】集合(516~561)

516.集合-每天一考 1.什么是枚举类?枚举类的对象声明的修饰符都有哪些? 枚举类:类中的对象的个数是确定的,有限个。 private final (No) public static final (Yes) 2.什么是元注解?说说Retention和Target元注解的作用…

516511

阿斯顿撒自行车墨迹墨迹快慢结合

ClickHouse exception code:516

当客户端连接clickhouse-server出现异常:ClickHouse exception, code: 516 , 经过分析错误码: ClickHouse exception, code: 516, host: 192.168.0.108, port: 8888; Code: 516, e.displayText() DB::Exception: default: Authentication f…

Leetcode.516 最长回文子序列

题目链接 Leetcode.516 最长回文子序列 题目描述 给你一个字符串 s,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例 1&#x…

【LeetCode-516】516.最长回文子序列(给定一个字符串s,找到其中最长的回文子序列,并返回该序列的长度。可以假设s的最大长度为1000。)

516.最长回文子序列 给定一个字符串s,找到其中最长的回文子序列,并返回该序列的长度。可以假设s的最大长度为1000。 解题思路:动态规划 超赞的解题思路 dp 数组的定义是:在子串 s[i…j] 中,最长回文子序列的长度为…

Apifox:详细使用教程,带你轻松拿捏

目录 Apifox简介 Apifox的安装与使用 Apifox新建项目的流程 编写接口文档 Apifox简介 我们在日常编程开发过程中经常实行的是前后端分离架构的模式,一个项目的落地会通过产品、开发、测试三方会审,对项目需求评审过后,前后端开发会制定一些接…

Navicat 受邀出席 PostgreSQL 技术峰会,欢迎莅临我们的展台了解 Navicat 工具包如何提升你的工作效能

Navicat 受邀出席 PostgreSQL 技术峰会成都站,欢迎童鞋们莅临我们的展台。你有机会与我们的专家面对面交流,并了解实用的 Navicat 工具包如何帮助PostgreSQL用户(应用开发人员、DBA、运维人员以及数据分析师)有效地提升日常的工作…

19.白盒测试逻辑覆盖有哪几种覆盖标准,覆盖率最高的是什么?

语句覆盖:设计若干测试用例,运行被测程序,使程序中每个可执行语句至少执行一次 优点:可以直观的从源代码得到测试用例缺点:仅仅针对程序逻辑中显式存在的语句,无法针对隐藏的条件进行测试。语句覆盖是最弱…