算法专题训练(3)回文字符串

这篇博客探讨了如何解决与回文字符串相关的算法问题,包括516题——求字符串中最大回文子串的最大长度,以及5.题——求最长回文子串。博主介绍了不同的解题思路,如利用翻转字符串找到最长公共子序列,以及使用动态规划的方法。此外,还提及了647题,关于计算字符串中回文子字符串的总数,并列出了未来要解决的730题——计数不同的回文子序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将s翻转成s1 求s和s1的最长公共子序列长度
可以先判断下s是否是回文
另外一个思路
dp[i][j] = dp[i + 1][j - 1] + 2 if s[i] == s[j]
dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]) otherwise

class Solution(object):
    def longestPalindromeSubseq(self, s):
        """
        :type s: str
        :rtype: int
        """
        size = len(s)
        s1 = s[::-1]
        if s1 == s: return size
        dp = [[0]*(size+1) for i in range(size+1)]
        for i in range(size):
            for j in range(size):
                if s[i]==s1[j]: 
                    dp[i+1][j+1] = dp[i][j]+1
                else:
                    dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j])
        return dp[size][size]

在每个字符的两边都插入一个特殊的符号’#’
定义 id 为已知的 {右边界最大} 的回文子串的中心,mx则为id+P[id],也就是这个子串的右边界

class Solution(object):
    def longestPalindrome(self,s):
        '''
        :param s: str
        :return: str
        '''
        ss = '$';idx=0;mx=0
        for i in s:
            ss = ss+'#'+i
        ss = ss+'#'
        P = [0 for i in range(len(ss))]
        for i in range(1,len(ss)):
            if P[idx]+idx<i:
                P[i] = 1
            else:
                P[i] = min(P[2*idx-i],P[idx]+idx-i) #对称点
            while(i+P[i]<len(ss) and ss[i-P[i]]==ss[i+P[i]]):
                P[i] = P[i]+1
            if idx + P[idx] < i + P[i]:
                idx = i
            if P[i]>P[mx]:
                mx = i
        a = ss[mx - (P[mx] - 1):mx + P[mx]]
        ret = ''
        for i in a:
            if i!='#':
                ret+=i
        return ret

判断s[i:j+1]是否是回文等价于判断s[i+1:j] 和 s[i][j]的情况

class Solution(object):
    def countSubstrings(self, s):
        """
        :type s: str
        :rtype: int
        """
        if s=='': return 0
        size = len(s)
        dp = [[0 for i in range(size)] for j in range(size)]
        ret = 0
        for i in range(size):
            dp[i][i]=1
            for j in range(i):
                if s[i]==s[j]:
                    if dp[i-1][j+1] or j==i-1:
                        dp[i][j] = 1
            ret += sum(dp[i])
        return ret

To do list
- 730. Count Different Palindromic Subsequences, Hard

### Python 实现回文字符串算法示例代码 以下是一个基于 Python 的回文字符串检测算法实现。该算法不仅能够判断一个字符串是否为回文,还提供了查找最长回文子串的功能[^1]。 ```python def is_palindrome(s: str) -> bool: """ 判断一个字符串是否为回文:param s: 输入的字符串 :return: 如果是回文返回 True,否则返回 False """ return s == s[::-1] def longest_palindrome(s: str) -> str: """ 查找字符串中的最长回文子串。 :param s: 输入的字符串 :return: 最长的回文子串 """ if not s or len(s) < 1: return "" start, end = 0, 0 def expand_around_center(left: int, right: int) -> int: """ 从中心扩展以找到最长回文子串的边界。 :param left: 左边界索引 :param right: 右边界索引 :return: 当前中心的最大回文长度 """ while left >= 0 and right < len(s) and s[left] == s[right]: left -= 1 right += 1 return right - left - 1 for i in range(len(s)): len1 = expand_around_center(i, i) # 奇数长度回文 len2 = expand_around_center(i, i + 1) # 偶数长度回文 max_len = max(len1, len2) if max_len > end - start: start = i - (max_len - 1) // 2 end = i + max_len // 2 return s[start:end + 1] ``` #### 示例运行 以下是上述代码的使用示例: ```python # 测试回文检测函数 test_str = "level" print(f"字符串 &#39;{test_str}&#39; 是否为回文: {is_palindrome(test_str)}") # 输出: True # 测试最长回文子串查找函数 input_str = "babad" result = longest_palindrome(input_str) print(f"字符串 &#39;{input_str}&#39; 的最长回文子串为: &#39;{result}&#39;") # 输出: &#39;bab&#39; 或 &#39;aba&#39; ``` 以上代码中,`is_palindrome` 函数通过简单的字符串反转比较来判断是否为回文[^2]。而 `longest_palindrome` 函数则采用“中心扩展法”来查找最长回文子串,这种方法的时间复杂度为 \(O(n^2)\),适合处理长度不超过 1000 的字符串[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值