classSolution:defisPalindrome(self, s:str)->bool:
s ="".join(ch.lower()for ch in s if ch.isalnum())return s == s[::-1]
双指针:
classSolution:defisPalindrome(self, s:str)->bool:
s ="".join(ch.lower()for ch in s if ch.isalnum())
n =len(s)
left, right =0, n-1while left < right:if s[left]!= s[right]:returnFalse
left, right = left+1, right-1returnTrue
原字符串判断:
classSolution:defisPalindrome(self, s:str)->bool:
n =len(s)
left, right =0, n-1while left < right:# 用while是因为不止一个,and后条件是因为可能都不是数字或字母,一定要充分测试whilenot s[left].isalnum()and left < right:
left +=1whilenot s[right].isalnum()and left < right:
right -=1if s[left].lower()!= s[right].lower():returnFalse
left, right = left+1, right-1returnTrue
正则表达式:
classSolution:defisPalindrome(self, s:str)->bool:
s = re.findall(r"[a-zA-Z0-9]", s)
s ="".join(s)return s[::-1]== s
分割回文串:验证+分割子串
回溯+动态规划:
classSolution:defpartition(self, s:str):
n =len(s)
f =[[True]* n for _ inrange(n)]# 注意动归方向for i inrange(n -1,-1,-1):for j inrange(i +1, n):
f[i][j]=(s[i]== s[j])and f[i +1][j -1]
ret =list()
ans =list()defdfs(i:int):if i == n:
ret.append(ans[:])returnfor j inrange(i, n):if f[i][j]:
ans.append(s[i:j+1])
dfs(j+1)
ans.pop()
dfs(0)return ret
回溯+记忆化搜索
classSolution:defpartition(self, s:str)-> List[List[str]]:
n =len(s)
ret =list()
ans =list()@cachedefisPalindrome(i:int, j:int)->int:if i >= j:return1return isPalindrome(i +1, j -1)if s[i]== s[j]else-1defdfs(i:int):if i == n:
ret.append(ans[:])returnfor j inrange(i, n):if isPalindrome(i, j)==1:
ans.append(s[i:j+1])
dfs(j +1)
ans.pop()
dfs(0)
isPalindrome.cache_clear()return ret
最长回文串:分割子串+验证
暴力解法:即两个for循环遍历所有情况
中心扩散:
classSolution:defexpandAroundCenter(self, s, left, right):while left >=0and right <len(s)and s[left]== s[right]:
left -=1
right +=1return left+1, right-1deflongestPalindrome(self, s:str)->str:
start, end =0,0for i inrange(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]
动态规划:
classSolution:deflongestPalindrome(self, s:str)->str:
n =len(s)if n <2:return s
max_len =1
dp =[[False]*n for _ inrange(n)]for i inrange(n):
dp[i][i]=Truefor j inrange(1, n):for i inrange(j):if j-i <=2:if s[i]== s[j]:
dp[i][j]=True
cur_len = j-i+1else:if s[i]== s[j]and dp[i+1][j-1]:
dp[i][j]=True
cur_len = j-1+1if dp[i][j]:if cur_len > max_len:
max_len = cur_len