难度:中等
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
思路(错误):回文最常见的一种思路是倒置在处理,我初步想法是倒置后,找原字符串和倒置字符串的最大公共字串,这个有用到了动态规划...又花了好久去学了一下...并整理了博客:ACM算法学习-动态规格 https://blog.csdn.net/RHJlife/article/details/104774665
不过该代码有个问题。。。目前还没解决,打算用动态规划问题直接解决本问题,错误之处应该是:找原字符串和倒置字符串的最大公共字串与题意并不等价
错误代码如下(实际的求最大公共字串代码):
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
x=s[::-1]
print(x)
len1 = len(s)
len2 = len(x)
res = [[0 for i in range(len1+1)] for j in range(len2+1)]
result = 0
#用于记录位置
flag=0
#动态规划
for i in range(1,len2+1):
for j in range(1,len1+1):
if x[i-1] == s[j-1]:
res[i][j] = res[i-1][j-1]+1
if res[i][j]>result:
result=res[i][j]
flag=i
return s[flag-result+1:flag+1]
错误样例:
输入:
"babad"
输出:
"bad"
预期:
"bab"
正确思路:本问题有三种解决方案:暴力、动态规划、马拉车算法,马拉车算法我这几天也研究了下,发现还是比较适合特定的某些题,还是以动态为主吧。
状态:dp[i][j] 表示子串 s[i, j] 是否为回文子串。
转移:这一步在做分类讨论(根据头尾字符是否相等),根据上面的分析得到:
dp[i][j] = dp[i + 1][j - 1] (s[i] == s[j]时)
初始化:单个字符一定是,所以对角线初始化为1
代码如下
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
m = len(s)
max_len = 1
#记录最长回文的头下标
flag = 0
if m < 2:
return s
#二维列表的快速创建方法
dp = [[0 for _ in range(m)] for _ in range(m)]
for i in range(m):
dp[i][i]=1;
for j in range(1,m):
for i in range(0,j):
if s[i] == s[j]:
if j-i < 3:
dp[i][j] = 1
else:
dp[i][j] = dp[i+1][j-1]
else:
dp[i][j] = 0
if dp[i][j]:
cur_len = j-i+1
if cur_len > max_len:
max_len = cur_len
flag = i
#返回的是字串而不是长度
return s[flag:flag+max_len]