数据结构与算法——字符串的中心扩展

一、最长回文子串

此题为leetcode第5题
思路:根据回文字符串的特点,如果以字符a为中心,各向两边扩散一个字符,这两个字符一样的话这个子串一定是回文子串,并且可以继续扩散;若扩散的两个字符不一样,那么这个子串一定不是回文子串,并且无法继续扩散。中心扩散的另一种形式是以一个空字符为中心向两边扩散,扩散的条件和上面的一样。所以我们需要定义一个check函数,传入开始扩散的左右起始点,一步一步向两边扩散,直到组不成回文子串位置,返回这个子串的长度。
在这里插入图片描述

class Solution:
    # 扩展中心
    def check(self, s, L, R):
        while(L >= 0 and R < len(s) and s[L]==s[R]):
            L -= 1
            R += 1
        return R - L -1
    
    def longestPalindrome(self, s: str) -> str:
        start, end = 0, 0
        for i in range(len(s)):
            # 以s[i]为中心扩散
            len1 = self.check(s, i, i)
            # 以s[i]和s[i+1]的中间为中心扩散
            len2 = self.check(s, i, i+1)
            length = max(len1, len2)
            # 最长子串为[start, end],更新最长子串的起始位置
            if length > (end - start + 1):
                start = i - int((length - 1)/2)   
                end = i + int(length/2)
        return s[start:end+1]

二、回文子串

此题为leetcode第647题
思路:此题比上一个题简单一点,依次遍历可能的中心点,挨个扩散,对回文子串计数即可。对于长度为n的字符串,可能的中心点有2 * n – 1个。注意扩散起始点L和R的计算。
在这里插入图片描述

class Solution:
    def countSubstrings(self, s: str) -> int:
        # 扩展中心
        n = len(s)
        res = 0
        for center in range(2 * n - 1):
            left = center // 2
            right = left + center % 2
            while left >= 0 and right <= n - 1 and s[left] == s[right]:
                res += 1
                left -= 1
                right += 1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值