我修改了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)时间和空间中工作。它计算长度很好,所以我需要以最优雅的方式回溯实际的回文,而不是牺牲效率来优雅。