题目描述
最大回文子串是被研究得比较多的一个经典问题。
最近月神想到了一个变种,对于一个字符串,如果不要求子串连续,那么一个字符串的最大回文子串的最大长度是多少呢。
- 输入描述
每个测试用例输入一行字符串(由数字0-9,字母a-z、A-Z构成),字条串长度大于0且不大于1000.
- 输出描述
输出该字符串的最长回文子串的长度。(不要求输出最长回文串,并且子串不要求连续)
- 示例
输入:adbca
输出:3
说明:因为在本题中,不要求回文子串连续,故最长回文子串为aba(或ada、aca)
动态规划
使用动态规划的思想,dp[front][rear]表示字符串s中位置front到位置rear的字符串中的最长回文子串的长度,那么存在两种情况:
-
当s[front]==s[rear]时,dp[front][rear]的大小等于其子串dp[front-1][rear+1]+2。
-
当s[front]!=s[rear]时,dp[front][rear]的大小为dp[front-1][rear]和dp[front][rear+1]中的最大值。
最后,dp[0][-1]就是这个字符串的最长回文子串的长度。
values = input().strip()
vl = len(values)
dp = [[0 for i in range(vl)] for j in range(vl)]
for rear in range(0, vl):
dp[rear][rear] = 1
for front in range(rear-1, -1, -1):
if values[front] == values[rear]:
dp[front][rear] = dp[front+1][rear-1] + 2
else:
dp[front][rear] = max(dp[front][rear-1], dp[front+1][rear])
print(dp[0][-1])
递归的方式
def longest_palindrome_substring(s):
return simple(0, len(s) - 1)
def simple(front, rear):
if front == rear:
return 1
if front > rear:
return 0
if s[front] == s[rear]:
return simple(front+1, rear-1) + 2
else:
return max(simple(front, rear-1), simple(front+1, rear))
if __name__ == '__main__':
s = input().strip()
print(longest_palindrome_substring(s))
提示“运行超时”,可采用以空间换时间,使用字典结构。
def longest_palindrome_substring(s):
dp = {}
def simple(front, rear):
if front == rear:
return 1
if front > rear:
return 0
if (front, rear) in dp:
return dp[(front, rear)]
if s[front] == s[rear]:
cur = simple(front+1, rear-1) + 2
else:
cur = max(simple(front, rear-1), simple(front+1, rear))
dp[(front, rear)] = cur
return cur
return simple(0, len(s) - 1)
if __name__ == '__main__':
s = input().strip()
print(longest_palindrome_substring(s))
(最近更新:2019年08月27日)
本文探讨了在不连续子串条件下寻找字符串中最大回文子串的问题,提供了动态规划和递归两种解决方案,旨在帮助读者理解并实现这一经典算法。
&spm=1001.2101.3001.5002&articleId=100107347&d=1&t=3&u=b6b58b8e70494adb8bda314982698388)
2606

被折叠的 条评论
为什么被折叠?



