将B视为一组分组符号(,),[,],{和}。如果B的长度为0或者B具有以下形式之一,则称为平衡序列:{X} Y或[X] Y或{X} Y其中X和Y本身是平衡的。 Balanced的示例:() - {[]()} [] - ...
现在的问题是找到一种有效的算法来找到给定输入的最大长度平衡子序列(不一定是连续的),该输入是这些分组符号的字符串。
例如,如果输入为(){([)] {(])}} [] ,则其中一个最大长度子序列为(){[] {() }} []
我几乎可以肯定解决方案是DP,但无论如何我解决了这个问题,我找到了算法不起作用的例子。我确信只有一种方法,即DP和Divide and Conquer的组合。但它效率不高,因为无论如何D& C部分将一遍又一遍地解决一些重叠问题。
答案 0 :(得分:5)
让我们做一些简单的观察:
任何平衡的子序列都可以表示为A1 X A2 Y
,其中A1
和A2
是两个匹配的括号((),[]或{}),{{1} }和X
是平衡的子序列(它们可以是空的)。这是事实,因为在任何平衡的非空子序列中都有一个最左边的括号,它必须与某些东西相匹配。
Y
和X
是独立的。如果不是这样,则子序列不平衡。
这些观察为我们提供了动态编程解决方案:
我们假设Y
是f(L, R)
子阵列中最长的平衡子序列。
基数是一个空的子阵列。过渡如下:
[L, R]
时间复杂度为f(L, R) = max(
f(L + 1, R) // ignore the first element
max(f(L + 1, K - 1) + 2 + f(K + 1, R)) for all K if brackets at positions L and K match
)
,因为有O(N^3)
个子数组,并且每个子数组都有O(N^2)
个转换。可以使用标准答案重建技术重建最长的子序列本身。