5. 最长回文子串
1、感觉动态规划用不上~
2、答案和我一开始想的差不多,不过它记录了开始和结尾两个坐标,我只想到用中心节点来代表一个子串。
3、运行好慢,不知道哪里错了,调试一下
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n<2:
return s
dp=[[False]*n for _ in range(n)]
for i in range(n):
dp[i][i]=True
max_len = 1
begin = 0
# L为总长度,为起始的index,可以推算出结尾的index——j
for L in range(2,n+1):
for i in range(n):
j = L+i-1
if j>n-1:
break
if s[i]!=s[j]:
pass
else:
if i-j<3:
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
begin = i
return s[begin:begin+max_len]
4、是j-i,不是i-j
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n<2:
return s
dp=[[False]*n for _ in range(n)]
for i in range(n):
dp[i][i]=True
max_len = 1
begin = 0
# L为总长度,为起始的index,可以推算出结尾的index——j
for L in range(2,n+1):
for i in range(n):
j = L+i-1
if j>n-1:
break
if s[i]!=s[j]:
pass
else:
if j-i<3:
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
begin = i
return s[begin:begin+max_len]
5、本题主要思想是通过子串长度和起始位置,把所有可能性遍历一遍,其中考虑得到动态规划的思想,最终终结于长度为1和2的情况(长度为1肯定为回文子串,在初始化中dp[i][i]已经体现,判断长度为2是不是)。将所有长度为1、2的判断完了,再根据长度为1的判断所有长度为3的;根据长度为2的判断长度为4的,形成动态规划
516. 最长回文子序列
1、感觉是上一道题的简化版,代码直接copy就好了
2、尴尬,看错题了
3、没什么想法
4、看了答案,中间的虽然在变化,并且可以去除,但是两边的保持不变呀
5、运行的时候出现问题——子问题未被处理过又看了答案,发现需要从后往前遍历i
6、好神奇,i逆向遍历的时候,就可以先处理子问题了。
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
if n==1:
return 1
dp=[[0]*n for _ in range(n)]
for row in range(n):
dp[row][row] = 1
for i in range(n-1,-1,-1):
for j in range(i+1,n):
if s[i]==s[j]:
if j-i<2:
dp[i][j] = 2
else:
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][n-1]
其实,i从0开始的话,相当于第一轮遍历就把最后的结果输出了,肯定是不合理的。没参透,但很神奇!