牛客网学习笔记(HJ85最长回文子串)

96 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目来自牛客网的华为机试题库,本题目为简单题

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个元素之间是不是回文数,刚刚看到这种类似解法的时候,我理解了好久,在纸上画了好多遍,觉得好神奇啊,怎么想到的,后来发现这就是常见套路啊!果然是俺见识短。