回溯最长的回文子序列

时间:2016-11-27 13:37:11

标签: python algorithm python-3.x dynamic-programming

我修改了Geeks for Geeks中的代码以回溯实际的子序列,而不仅仅是它的长度。但是当我回溯到最后,我可以将任意角色放在回文的中间时,我发现我的解决方案是草率而不是“Pythonic”#39;有人可以帮帮我吗?

这件作品闻起来特别糟糕(如果它可以正常工作):

if length_matrix[start][end] == 1 and substr_length >= 0:
    middle = sequence[start]

这是前锋:

def calc_subsequence_lengths(sequence):
    n = len(sequence)

    # Create a table to store results of subproblems
    palindrome_lengths = np.zeros((n, n))

    # Strings of length 1 are palindrome of length 1
    np.fill_diagonal(palindrome_lengths, 1)

    for substr_length in range(2, n + 1):
        for i in range(n - substr_length + 1):
            j = i + substr_length - 1
            if sequence[i] == sequence[j] and substr_length == 2:
                palindrome_lengths[i][j] = 2
            elif sequence[i] == sequence[j]:
                palindrome_lengths[i][j] = palindrome_lengths[i + 1][j - 1] + 2
            else:
                palindrome_lengths[i][j] = max(palindrome_lengths[i][j - 1], 
                                               palindrome_lengths[i + 1][j])
    return palindrome_lengths

这是追溯:

def restore_palindrome(length_matrix, sequence):
    palindrome_left = ''
    middle = ''
    n, n = np.shape(length_matrix)
    # start in the north-eastern corner of the matrix
    substr_length, end = n - 1, n-1
    # traceback
    while substr_length > 0 and end > 1:
        start = end - substr_length
        # if possible, go left
        if length_matrix[start][end] == (length_matrix[start][end - 1]):
            substr_length -= 1
            end -= 1
        # the left cell == current - 2, but the lower is the same as current, go down
        elif length_matrix[start][end] == (length_matrix[start + 1][end]):
            substr_length -= 1
        # both left and lower == current - 2, go south-west
        else:
            palindrome_left += sequence[start]
            substr_length -= 2
            end -= 1
    if length_matrix[start][end] == 1 and substr_length >= 0:
        middle = sequence[start+1]
    result = ''.join(palindrome_left) + middle + ''.join(palindrome_left[::-1])
    return result, int(length_matrix[0][n-1])

更新

首先,问题是计算最长的非连续的回文序列(如我在上面提到的文章中所述)。对于序列BBABCBCAB,输出应为BABCBAB 其次,正如我已经指出的那样,我建立在现有的DP解决方案的基础上,该解决方案在O(N ^ 2)时间和空间中工作。它计算长度很好,所以我需要以最优雅的方式回溯实际的回文,而不是牺牲效率来优雅。

0 个答案:

没有答案