Dynamic programming and center diffusion method to solve the problem of palindrome number (implemented in python)

problem

  This question is a medium-difficulty problem, but there are various methods, which are worth recording. The questions are as follows:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

  Three methods are given below: brute force solution, central diffusion and dynamic programming.

answer

Violent solution

  The first thing that comes to mind is the brainless violent solution, traversing from left to right, remembering the initial length of a string is 1. When the traversal finds a palindrome substring, the length of the string is increased by one, and it keeps increasing until the length is not found. The palindrome substring. This method is easier to come up with, but due to the traversal, the time complexity is higher, and the calculation time is also higher.

  There are two ways to determine whether it is a palindrome substring:

  1. The string length n is an odd number, 0 to n − 1 2 \frac{n-1}{2}2n1And n + 1 2 \frac{n+1}{2}2n+1 The substring to n is an inverted relationship, only need to judge to verify whether it is a palindrome number string;

  2. The string length n is an even number, divide the string into two equally spaced segments, and judge whether it is an inverted relationship.

    The code is as follows:

 def judge_Palindrome(s):
     if len(s) % 2 == 1:   # odd
         if s[0:int(len(s) / 2)] == s[:int(len(s) / 2):-1]:
             return True
         else:
             return False
     elif len(s) % 2 == 0:   # even
         if s[0:int(len(s) / 2)] == s[-1:-int(len(s) / 2) - 1:-1]:
             return True
         else:
             return False

  The next idea is the same as the one mentioned at the beginning, just traverse:

if len(s) < 2:
    l = s
else:
    l = s[0]
    i = 2
    while i <= len(s):
        for start_node in range(0, len(s) - i + 1):
            if judge_Palindrome(s[start_node:start_node + i]):
                l_longest = i
                l = s[start_node:start_node + i]
                break
            else :
                continue
        i = i + 1

Center spread

  It is also traversed from left to right, with each element as a center, spreading left and right to the end of the longest palindrome that can be satisfied.

def center_spread(s, size, left, right):
    i = left
    j = right
    
    while i >= 0 and j < size and s[i] == s[j]:
        i -= 1
        j += 1
    return s[i + 1:j], j - i - 1    

if len(s) < 2:
    l = s
else :
    max_len = 1
    l = s[0]
    
    for i in range(len(s)):
        l_odd, odd_len = center_spread(s, len(s), i, i)
        l_even, even_len = center_spread(s, len(s), i, i + 1)
        # find the current maximum length
        cur_max_l = l_odd if odd_len > even_len else l_even
        if len(cur_max_l) > max_len:
            max_len = len(cur_max_l)
            l = cur_max_l

Dynamic programming

  There are two key points:

  1. Define "state"

    d p [ l ] [ r ] dp[l][r] d p [ l ] [ r ] represents the substrings [l, r] s[l, r]s[l,r ] (including the left and right endpoints of the interval) whether it constitutes a palindrome string is a two-dimensional Boolean array. That is, if the substrings [l, r] s[l, r]s[l,r ] is a palindrome, thendp [l] [r] = T rue dp[l][r] = Truedp[l][r]=True

  2. Find the "state transition equation"

dp[l, r] = (s[l] == s[r] and (r - l <= 2 or dp[l + 1, r - 1]))

  When s [l, r] s[l,r]s[l,When r ] is a text string, undoubtedly,s [l + 1, r − 1] s[l+1,r-1]s[l+1,r1 ] is also a text string, the only thing to note is that whens [l + 1, r − 1] s[l+1,r-1]s[l+1,r1 ] When there is only 1 or no element, it cannot be judged by dp, but at this time it must be a text string, becauses [l] = s [r] s[l] = s[r]s[l]=s[r]

The code is given below:

size = len(s)
if size < 2:
    res = s
else :
    dp = [[False for _ in range(size)] for _ in range(size)]
    longest_l = 1
    res = s[0]
    for r in range(1, size):
        for l in range(size):
            if s[l] == s[r] and (r - l <= 2 or dp[l + 1][r - 1]):
                dp[l][r] = True
                cur_len = r - l + 1
                if cur_len > longest_l:
                    longest_l = cur_len
                    res = s[l:r + 1]

− − − − − − − − − − − − − − − − ---------------- - -
This article first appeared inzyairelu.cn
Welcome to my website to comment and discuss
personal mailbox [email protected]
- - - - - - - - - - - - - - - - -------- --------

Guess you like

Origin blog.csdn.net/weixin_42731543/article/details/102767373