A string is palindromic if it reads the same forward and backward.
- Palindrome 问题通常都可以用双指针
- 需要分别考虑奇数长度和偶数长度的情况
解析
- 有palindromic sub-str 包含奇数和偶数长度两种情况
# burte force
# - time: O(n^3) # n to check a sub-str being a palindrome or not, n^2 to chekc all possible sub-str
# - space: O(1)
# - Get every possible substring (O(n^2)), and check whether it is a palindrome (O(n))
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
res, resLen = "", 0
for i in range(len(s)):
for j in range(i, len(s)):
l, r = i, j
while l < r and s[l] == s[r]:
l += 1
r -= 1
# l >= r 以判断 l 和 r 是否相遇了,如果相遇了,说明 s[i:j+1] 为 palindrome
if l >= r and resLen < (j - i + 1):
res = s[i: j + 1]
resLen = j - i + 1
return res
# 双指针
# - time: O(n^2)
# - space: O(1)
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
maxLen = 0
res = ""
for i in range(len(s)):
# odd length, e.g., cbc in cbc
l, r = i, i
while l >= 0 and r < len(s) and s[l] == s[r]:
curLen = r - l + 1 # 计算两指针包括的元素长度
if curLen > maxLen:
maxLen = curLen
res = s[l:r + 1]
l -= 1
r += 1
# even length, e.g., bb in cbbc
l, r = i, i + 1
while l >= 0 and r < len(s) and s[l] == s[r]:
curLen = r - l + 1 # 计算两指针包括的元素长度
if curLen > maxLen:
maxLen = curLen
res = s[l:r + 1]
l -= 1
r += 1
return res
# ??
# Manacher's Algorithm
# - time: O(n)
# - space: O(1)
def longestPalindrome(self, s: str) -> str:
def manacher(s):
t = '#' + '#'.join(s) + '#'
n = len(t)
p = [0] * n
l, r = 0, 0
for i in range(n):
p[i] = min(r - i, p[l + (r - i)]) if i < r else 0
while (i + p[i] + 1 < n and i - p[i] - 1 >= 0
and t[i + p[i] + 1] == t[i - p[i] - 1]):
p[i] += 1
if i + p[i] > r:
l, r = i - p[i], i + p[i]
return p
p = manacher(s)
resLen, center_idx = max((v, i) for i, v in enumerate(p))
resIdx = (center_idx - resLen) // 2
return s[resIdx : resIdx + resLen]
ref
...