算法3--最长回文子串

发布于:2025-03-22 ⋅ 阅读:(126) ⋅ 点赞:(0)

题目描述

在这里插入图片描述

补充一点: 回文串就是正着读和反着读都一样的字符串。

解题思路

题目看着很简单不是吗? 实则不然,算法题越是题目描述的简单的,可能背后的逻辑就越复杂。

一个顺着题目描述的解法

一个比较容易想到的解法是:首先判断字符串的长度,如果长度为0或者1,那么就可以直接返回了,本身就是最长回文子串。

如果长度为2,那么就判断这个字符串所包含的两个字符是不是一样的字符,如果是,那么返回字符串本身,如果不是,那么返回字符串的第一个字符。

如果字符串长度大于2,那么需要遍历字符串,每次遍历时判断子字符串是不是回文子串,如果是的话,那就直接返回。

如果字符串以上条件都不满足,即它长度大于2,并且内部没有长度大于1的回文子串,那就返回字符串的第一个字符。

根据上面的思路可以完成代码。

class Solution:
    def longestPalindrome(self, s: str) -> str:
        res = ''
        if len(s) <= 1:
            return s
        if len(s) == 2:
            if s[0] == s[1]:
                return s
            else:
                return s[0]
        for i in range(len(s)):
            rest = s[i+1:]
            temp_s = s[i]
            for j in rest:
                temp_s += j
                if temp_s == temp_s[::-1]:
                    res = temp_s if len(temp_s) >= len(res) else res
        if res == '':
            return s[0]
        return res

尝试提交,通过,时间复杂度为O(n^3)
在这里插入图片描述

有优雅一些的解法吗?当然😎

很显然上面那种解法不断的判断字符串的长度,太不优雅了!

经过思考,题目要求的是最长回文子串,那么我们换个思路,从字符串本身去最长子串,每次判断最长字串是否为回文子串,如果是,那么它肯定就是最长回文子串,那么就返回,如果不是,那么就缩短最长子串的长度,继续判断。

这就类似于滑动窗口的思想,比如输入的字符串长度为10,那么就直接令窗口大小为10,判断窗口内的字符串是否为回文子串,如果是,那么就返回,如果不是,那么就缩短窗口大小,通过不断在父字符串上的滑动继续判断。

开始手搓!

class Solution:
    def longestPalindrome(self, s: str) -> str:
        res = s[0]
        window = len(s)
        while window >= 1:
            for i in range(len(s)-window+1):
                temp_s = s[i:i+window]
                if temp_s == temp_s[::-1]:
                    res = temp_s if len(temp_s) > len(res) else res
                    return res
            window -= 1
        return res

通过不断的减小窗口大小,就能够第一时间找出最长回文子串。

尝试提交,通过,时间复杂度为O(n^3),好像跟上面的解法是一样的时间消耗,但是可以看到运行所花的时间是第一种算法的50%都不到。也算是优雅了!
在这里插入图片描述