アルゴリズム: 最長回文部分文字列 5. 最長回文部分文字列

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. 動的プログラミングソリューション

  1. 動的計画法の式s[i] == s[j] and dp[i+1][j-1]、両端が等しく、サブセットがdp[i+1][j-1]検証されている場合、回文を次のように展開します。[i, j]
  2. 小さいものから大きいものまでありますので、ステップサイズの差分を設定する必要があります。シングルステップの問題に優先順位を付ける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]

おすすめ

転載: blog.csdn.net/zgpeace/article/details/131389526