当前位置:网站首页>动态规划:最长回文子串和子序列
动态规划:最长回文子串和子序列
2022-07-03 03:28:00 【我家大宝最可爱】
1. 回文子串
回文串就是正着读和反着读都一样的字符串,例如aba,aabb等,给定一个字符串,求最长回文子串。注意子串是指连续的
1.1左右扩展
左右扩展的思想很有意思,如果一个问题用到了左右扩展的想法,那么久直接定以两个范围l,r
,这样就可以避免奇偶问题了
一种非常直接的想法就是从某个字符开始,向两边开始搜索,然后匹配字符是否相等
<—向左搜索 | 某个字符 | 向右搜索—> | |
---|---|---|---|
字符串 | a | b | a |
搜索边界 | l | r |
很容易想到有奇偶两种情况,当为奇数(‘aba’)时l=r=i
,然后分别向两边移动,当为偶数(‘aabb’)时l=i,r=i+1
def helper(s,l,r):
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1
r += 1
return s[l+1:r]
def longs(s):
res = ''
for i in range(len(s)):
tmp = helper(s,i,i) # 奇数
if len(tmp) > len(res):res = tmp
tmp = helper(s,i,i+1) # 偶数
if len(tmp) > len(res):res = tmp
print(len(res))
s = input()
n = len(s)
longs(s)
1.2 动态规划
动态规划的想法也是非常简单的,假如i+1~j-1
之间的字符串时回文字符串,那么如果s[i]==s[j]
则i~j
之间的字符串也是回文子串,如果不相等,那么则不是回文子串,由此可以列出状态转移方程dp[i][j]=dp[i+1][j-1] and s[i]==s[j]
。然后我们考虑初始条件,如果i==j
则dp[i][i]=True
,一个字符肯定时回文串,两个字符和三个字符时则为dp[i][j] = (s[i] == s[j])
,只需要考虑两边的字符即可。
可以看到,计算dp[i][j]
用到了未来的状态dp[i+1][j]
,因此i需要反向迭代,即大到小。
原始字符串 | a | b | c | a | c | b | a |
---|---|---|---|---|---|---|---|
子序列1 | a | b | b | a |
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
dp = [[False for j in range(n)] for i in range(n)]
max_len = 0
max_str = ''
for i in range(n-1,-1,-1):
for j in range(i,n):
if s[i] == s[j]:
if j-i<=2:
dp[i][j] = True
else:
dp[i][j] = dp[i+1][j-1]
if dp[i][j] and j - i + 1 > max_len:
max_len = j - i + 1
max_str = s[i:j+1]
return max_str
最长回文子序列
子序列跟子串的一个最主要的区别在于是否连需,字符时不需要连需的,举个例子
原始字符串 | a | b | c | a | b | c | a |
---|---|---|---|---|---|---|---|
子序列1 | a | b | b | a | |||
子序列2 | a | c | c | a | |||
子序列3 | a | a | a | ||||
子序列4 | a | c | a | c | a | ||
子序列5 | a | b | a | b | a | ||
子序列n | … |
可以看到回文子序列时完全不需要连续的,那么现在的问题就是如何求解最长子序列呢?假如我们求出了i+1~j-1
之间的最长子序列,那么如何求解i~j
之间的最长子序列呢?
i | i+1 | j-1 | j | |||||
---|---|---|---|---|---|---|---|---|
s[i] | a | b | c | a | b | c | a | s[j] |
我们假设dp[i+1][j-1]是字符串i+1~j-1的最长回文子序列的长度,
- 当
s[i]==s[j]
时,有dp[i][j] = dp[i+1][j-1]+2
i | i+1 | j-1 | j | |||||
---|---|---|---|---|---|---|---|---|
s[i] | a | b | c | a | b | c | a | s[j] |
- 当
s[i]!=s[j]
时,这个时候就有意思了,也会分成两种情况,第一种时求i+1~j
之间的最长回文序列,第二种就是求i~j-1
之间的最长回文子序列
i | i+1 | j-1 | j | ||||||
---|---|---|---|---|---|---|---|---|---|
原始 | s[i] | a | b | c | a | b | c | a | s[j] |
i+1~j | a | b | c | a | b | c | a | s[j] | |
i~j-1 | s[i] | a | b | c | a | b | c | a |
此时有dp[i][j]=max(dp[i][j-1],dp[i+1][j])
状态转移方程我们已经得到了,下一步就是看看base,可以知道dp[i][i]=1
,因为我们时从i~j
,所以有j>i
,如果j<i
,那么就不可能得到回文序列,因此有dp[i][j]=0 if j < i
现在就剩一个边界问题了,求dp[i][j]
需要用到dp[i+1][j]
,即求解i位置的时候用到了未来的i+1位置,为了保证可以正常计算,我们需要将i按照递减的方式来更新,j则用到了j和j-1,所以使用递增计算即可
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
dp = [[1 if i==j else 0 for i in range(n)] for j in range(n)]
for i in range(n-1,-1,-1):
for j in range(i+1,n):
if s[i] == s[j]:
dp[i][j] = dp[i+1][j-1] + 2
else:
dp[i][j] = max(dp[i+1][j],dp[i][j-1])
return dp[0][-1]
边栏推荐
- 渤、黄海的潮汐特征
- 2020-01-01t00:00:00.000000z date format conversion
- Summary of matrix knowledge points in Chapter 2 of Linear Algebra (Jeff's self perception)
- Elsevier latex submitted the article pdftex def Error: File `thumbnails/cas-email. jpeg‘ not found: using draf
- Pytoch configuration
- [mathematical logic] propositions and connectives (propositions | propositional symbolization | truth connectives | no | conjunction | disjunction | non truth connectives | implication | equivalence)
- Vs 2019 configuration tensorrt
- Mysql Mac版下载安装教程
- 递归:快速排序,归并排序和堆排序
- Avec trois. JS fait une scène 3D simple
猜你喜欢
Gavin teacher's perception of transformer live class - rasa project's actual banking financial BOT Intelligent Business Dialogue robot architecture, process and phenomenon decryption through rasa inte
C programming learning notes [edited by Mr. Tan Haoqiang] (Chapter III sequence programming) 05 data input and output
User value is the last word in the competition of mobile phone market
MongoDB簡介
900w+ data, from 17s to 300ms, how to operate
MongoDB简介
Summary of electromagnetic spectrum
npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
Limit of one question per day
Latest version of NPM: the "NPM" item cannot be recognized as the name of a cmdlet, function, script file, or runnable program. Please check
随机推荐
FileZilla Client下载安装
Mysql Mac版下载安装教程
numpy之 警告VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences
C# WebRequest POST模式 ,基于“Basic Auth”口令认证模式,使用multipart/form-data方式上传文件及提交其他数据
[mathematical logic] predicate logic (individual word | individual domain | predicate | full name quantifier | existence quantifier | predicate formula | exercise)
可分离债券与可转债
403 error displayed when vs cloning
Lvgl usage experience
labelme标记的文件转换为yolov5格式
MongoDB复制集【主从复制】
MongoDB簡介
2020-01-01t00:00:00.000000z date format conversion
Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!
Avec trois. JS fait une scène 3D simple
用Three.js做一個簡單的3D場景
Vs 2019 configure tensorrt to generate engine
Pat class B "1104 forever" DFS optimization idea
Summary of electromagnetic spectrum
Idea set method call ignore case
Learning notes of C programming [compiled by Mr. Tan Haoqiang] (Chapter III sequence programming) 04 C sentence