快手:回文字符串(Python语言实现)

本文探讨了在不连续子串条件下寻找字符串中最大回文子串的问题,提供了动态规划和递归两种解决方案,旨在帮助读者理解并实现这一经典算法。

题目描述

最大回文子串是被研究得比较多的一个经典问题。
最近月神想到了一个变种,对于一个字符串,如果不要求子串连续,那么一个字符串的最大回文子串的最大长度是多少呢。
  • 输入描述
每个测试用例输入一行字符串(由数字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日)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值