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