最長の回文部分文字列-LeetCode(leetcode-cn.com)
文字列sが与えられた場合、sで最長の回文部分文字列を見つけます。
例1:
入力:s = "babad"
出力: "bab"
説明: "aba"は、質問の意味を満たす答えでもあります。
例2:入力:s = "cbbd"
出力: "bb"
ヒント:
1 <= s.length <= 1000
sは、数字と英字のみで構成されますソース:LeetCode
動的計画法
アイデア:dp [i] [j]を、文字列のi番目の文字からj番目の文字の終わりまでの文字列が回文であるかどうかとして定義します。
(i <= j)
部分文字列s[l、r]、s [l + 1:r-1]が回文である場合は、s[l]とs[r]が等しいかどうかを確認してください。
即dp[l][r] = dp [l +1][r-1]およびs[l]== s [r]
特別な場合、l + 1がr-1に等しい場合、2つのエンドポイントの間に要素が1つしかないことを意味します。
dp [l] [r] = True if s [l] == s [r] else False、実際、要素はそれ自体が回文であるため、上記のケースも組み込むことができます。
l + 1> r-1の場合、2つのエンドポイントの間に要素がないことを意味し、s[i]とs[r]が等しいかどうかを直接判断するだけで済みます。
上記の説明では、2つのエンドポイントを強調しましたが、i <= jであるため、i = jの場合、2つのポイントが重なり、直接割り当てを行うことができます。
要約:方程式の意味を定義し、状態遷移方程式を見つけ、状態遷移方程式に基づいて境界条件を決定します。
class Solution:
def longestPalindrome(self, s: str) -> str:
n=len(s)
dp=[[False]*n for i in range(n)]
dp[n-1][n-1]=True
a,b,ans=0,0,0
for l in range(n-2,-1,-1):
for r in range(l,n):
if l==r:
dp[l][r]=True
elif l+1>r-1:
dp[l][r]=True if s[l]==s[r] else False
else:
dp[l][r]=dp[l+1][r-1] and s[r]==s[l]
if dp[l][r] and r-l>=ans:
a,b,ans=l,r,abs(l-r)
return s[a:b+1]