一、最长回文子串
此题为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