本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目来自牛客网的华为机试题库,本题目为简单题
HJ85 最长回文子串
描述
给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串
输入描述:
输入一个仅包含小写字母的字符串
输出描述:
返回最长回文子串的长度
示例1
输入:
cdabbacc
输出:
4
说明:
abba为最长的回文子串
穷举法:
while True:
try:
s = input()
res = []
for i in range(len(s)):
for j in range(i+1, len(s)+1):
if s[i:j] == s[i:j][::-1]:
res.append(j-i)
if res != '':
print(max(res))
except:
break
动态规划
while True:
try:
s = input()
n = len(s)
if n < 2:
print(n)
max_len = 1
begin = 0
# dp[i][j] 表示 s[i..j] 是否是回文串
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True
# 递推开始
# 先枚举子串长度
for L in range(2, n + 1):
# 枚举左边界,左边界的上限设置可以宽松一些
for i in range(n):
# 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
j = L + i - 1
# 如果右边界越界,就可以退出当前循环
if j >= n:
break
if s[i] != s[j]:
dp[i][j] = False
else:
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
print(max_len)
except:
break
解析
首先出场的就是我用的超级小白笨方法,直接穷举,然后直接倒过来看是不是相等,但是会超时,显然出题人不是想让这么解的
然后是新学到的方法,动态规划。用矩阵里的第i行j列来表示第j个和第i个元素之间是不是回文数,刚刚看到这种类似解法的时候,我理解了好久,在纸上画了好多遍,觉得好神奇啊,怎么想到的,后来发现这就是常见套路啊!果然是俺见识短。