5. 最長の回文部分文字列
文字列 s を指定すると、最長の
回文を返します。
s の部分文字列
。
例 1:
Input: s = "babad"
Output: "bab"
Explanation: "aba" is also a valid answer.
例 2:
Input: s = "cbbd"
Output: "bb"
制約:
- 1 <= s.length <= 1000
- s は数字と英字のみで構成されます。
1. 2 つのポインターの解決策、中央の位置が単数か倍数かに注意してください。
class Solution:
def longestPalindrome(self, s: str) -> str:
def expand(i, j):
left = i
right = j
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return right - left - 1
ans = [0, 0]
for i in range(len(s)):
odd_len = expand(i ,i)
if odd_len > ans[1] - ans[0] + 1:
dist = odd_len // 2
ans = [i - dist, i + dist]
even_len = expand(i, i+1)
if even_len > ans[1] - ans[0] + 1:
dist = (even_len // 2) - 1
ans = [i - dist, i + 1 + dist]
i, j = ans
return s[i: j+1]
2. 動的プログラミングソリューション
- 動的計画法の式
s[i] == s[j] and dp[i+1][j-1]
、両端が等しく、サブセットがdp[i+1][j-1]
検証されている場合、回文を次のように展開します。[i, j]
- 小さいものから大きいものまでありますので、ステップサイズの差分を設定する必要があります。シングルステップの問題に優先順位を付ける
s[i] == s[i+1]
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
dp = [[False] * n for _ in range(n)]
ans = [0, 0]
for i in range(n):
dp[i][i] = True
for i in range(n - 1):
if s[i] == s[i+1]:
dp[i][i+1] = True
ans = [i, i+1]
for diff in range(2, n):
for i in range(n - diff):
j = i + diff
if s[i] == s[j] and dp[i+1][j-1]:
dp[i][j] = True
ans = [i, j]
i, j = ans
return s[i: j+1]