找到最大平衡子阵列

时间:2015-02-15 17:09:46

标签: algorithm dynamic-programming

给定一个字符括号数组和一个整数数组。

我们需要在整数数组中找到最大和子子数组,使得字符数组中相应的子数组具有平衡括号。 形式上,平衡括号是{[,],{,},<,>,(,)} *的子集,递归定义如下:

The empty string is balanced parentheses.
If A is balanced parentheses, then so are the strings [A], {A} , <A>, (A).
If A and B are balanced parenthesis, then so is the string AB.

设N = 4,字符数组为:()(),整数数组为-1 -2 3 4则答案为7,为最后2个元素:3 + 4 = 7。

如何找到给定字符数组和整数数组的最大总和?

我正在检查最大子阵列,然后检查它是否平衡并继续它直到我得到平衡。但这效率低下。他们的任何有效方式是N&lt; = 10 ^ 5

1 个答案:

答案 0 :(得分:2)

使用push down automaton,您可以创建查找括号平衡的所有位置。这将是一系列索引i_1,i_2,...,i_k。假设数组本身是平衡的,i_k = n-1(基于0的索引)。
以上可以在线性时间内完成。

使用上述方法,您可以创建辅助阵列,定义为:

aux[k] = intArray[i_(k-1) + 1] + intArray[i_(k-1) + 2] + ... + intArray[i_(k)-1] + intArray[i_k]

单词:元素k是元素i_(k-1)(不包括)到i_k(包括)的元素之和。 (i_0被定义为i_0=-1以简化事情。)

以上是包含所有具有相应平衡括号的和的数组,现在可以在aux上调用“常规”最大和算法,以找到答案。

正确性的证明将基于以下事实:每组平衡括号(包括最优的括号)是最大子阵列算法的候选者,aux中的每个子阵列都是平衡括号系列。< / p>

伪代码:
假设存在findMaxSubArray(arr)返回“常规”最大子阵列算法:

stack s = new Stack()
cands= new list
cands.add(-1)
for (int i = 0; i < parantheses.length; i++)
   if parantheses[i] == '(' ||  parantheses[i] == '[' || parantheses[i] == '{':
       stack.push(parantheses[i]) 
       continue
   if stack.peek() == '(' && parantheses[i] == ')':
       stack.pop() //remove head of stack
   else if stack.peek() == '[' && parantheses[i] == ']':
      stack.pop()
   //similar line for '}'
   if stack.isEmpty(): //found balanced subarray
        cands.add(i)
//at this point we have a list cands containing ends of all valid parantheses.
//we now wish to make aux of the corresponding sums
int[] aux = new int[cands.length - 1];
for (int i = 1; i<aux.length; i++)
     start = cands.get(i-1)
     end = cands.get(i)
     aux[i-1] = 0
     for (int j = start+1; j<= end; j++):
        aux[i-1] += intsArray[j];
     //when done, aux[i-1] is the sum of balances parantheses cands_{i-1} until cands_i
//we have established our aux array
return findMaxSubArray(aux)