type1:动态规划
将原字符串反转后,对原字符串和反转字符串,类似最长公共子序列求解。
516. 最长回文子序列
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
ss = s[::-1]
#以下开始最长公共子序列求解
n=len(s)
dp=[[0]*(n+1) for _ in range(n+1)]
for i in range(1,n+1):
for j in range(1,n+1):
if s[i-1]==ss[j-1]:
dp[i][j]=dp[i-1][j-1]+1
else:
dp[i][j]=max(dp[i-1][j], dp[i][j-1])
return dp[n][n]
type2:中心扩展法
先给出中心对及中心对个数,然后再对每个中心对进行扩展判断。
647. 回文子串
给你一个字符串 s ,返回这个字符串中 回文子串 的数目。
条件:具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
class Solution:
def countSubstrings(self, s: str) -> int:
n=len(s)
ans=0 #记录回文字串的个数
for i in range(2*n-1): #2n-1个中心对
left,right=i//2,i//2+i%2
while left>=0 and right<n and s[left]==s[right]:
left-=1
right+=1
ans+=1
return ans
5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
#解法一
class Solution:
def longestPalindrome(self, s: str) -> str:
n=len(s)
start,end=0,0 #记录最长回文字串的起始下标
for i in range(2*n-1):
left,right=i//2,i//2+i%2
while left>=0 and right<n and s[left]==s[right]:
left-=1
right+=1
if end-start+1<(right-1)-(left+1)+1:
start,end=left+1,right-1
return s[start:end+1]
#解法二
class Solution:
def longestPalindrome(self, s: str) -> str:
def expandAroundCenter(s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return left+1, right-1 #记录能扩展的最远下标
start, end = 0, 0 #end-start记录最长回文子串长度
for i in range(len(s)):
left1, right1 = self.expandAroundCenter(s, i, i)
left2, right2 = self.expandAroundCenter(s, i, i + 1)
if right1 - left1 > end - start:
start, end = left1, right1
if right2 - left2 > end - start:
start, end = left2, right2
return s[start: end + 1]
type3:数学法
866. 回文素数
求出大于或等于 N 的最小回文素数。
class Solution:
def primePalindrome(self, n: int) -> int:
import math
def reverse(N): #求整数的反转整数
ans=0
while N>0:
ans = 10*ans+N%10
N = N//10
return ans
def isPrime(N): #整数是否素数
if N==1:
return False
for i in range(2,int(math.sqrt(N))+1):
if N%i==0:
return False
return True
while True:
if n==reverse(n) and isPrime(n):
return n
n+=1
if 10**7<n<10**8:
n=10**8