2021-08-09 字符串:回文串
验证回文串
class Solution:
def isPalindrome(self, s: str) -> bool:
s = "".join(ch.lower() for ch in s if ch.isalnum())
return s == s[::-1]
class Solution:
def isPalindrome(self, s: str) -> bool:
s = "".join(ch.lower() for ch in s if ch.isalnum())
n = len(s)
left, right = 0, n-1
while left < right:
if s[left] != s[right]:
return False
left, right = left+1, right-1
return True
class Solution:
def isPalindrome(self, s: str) -> bool:
n = len(s)
left, right = 0, n-1
while left < right:
while not s[left].isalnum() and left < right:
left += 1
while not s[right].isalnum() and left < right:
right -= 1
if s[left].lower() != s[right].lower():
return False
left, right = left+1, right-1
return True
class Solution:
def isPalindrome(self, s: str) -> bool:
s = re.findall(r"[a-zA-Z0-9]", s)
s = "".join(s)
return s[::-1] == s
分割回文串:验证+分割子串
class Solution:
def partition(self, s: str):
n = len(s)
f = [[True] * n for _ in range(n)]
for i in range(n - 1, -1, -1):
for j in range(i + 1, n):
f[i][j] = (s[i] == s[j]) and f[i + 1][j - 1]
ret = list()
ans = list()
def dfs(i: int):
if i == n:
ret.append(ans[:])
return
for j in range(i, n):
if f[i][j]:
ans.append(s[i:j+1])
dfs(j+1)
ans.pop()
dfs(0)
return ret
class Solution:
def partition(self, s: str) -> List[List[str]]:
n = len(s)
ret = list()
ans = list()
@cache
def isPalindrome(i: int, j: int) -> int:
if i >= j:
return 1
return isPalindrome(i + 1, j - 1) if s[i] == s[j] else -1
def dfs(i: int):
if i == n:
ret.append(ans[:])
return
for j in range(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循环遍历所有情况
- 中心扩散:
class Solution:
def expandAroundCenter(self, s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return left+1, right-1
def longestPalindrome(self, s: str) -> str:
start, end = 0, 0
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]
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
max_len = 1
dp = [[False]*n for _ in range(n)]
for i in range(n):
dp[i][i] = True
for j in range(1, n):
for i in range(j):
if j-i <= 2:
if s[i] == s[j]:
dp[i][j] = True
cur_len = j-i+1
else:
if s[i] == s[j] and dp[i+1][j-1]:
dp[i][j] = True
cur_len = j-1+1
if dp[i][j]:
if cur_len > max_len:
max_len = cur_len