有效括号序列的条件是:
所以,从原来的开闭括号串,我们可以把它转换成数字序列,每个数字代表从序列开始的开括号和右括号的区别。每个开括号,我们将加一,减一为关闭。
例如,对于((()))))
->,我们有序列 { 1, 2 , 3, 2 , 1, 0, -1, -2 }
因此,要测试子字符串是否有效,例如子字符串 (2, 5),即()))
,我们需要查看是否在任何时候,打开和关闭之间的差异是否为负。从上面的序列中,我们有 {3, 2, 1, 0},我们需要为每个元素减 2,因为我们需要从字符串的开头删除那些不在子字符串中的括号。-> 我们有 {1, 0, -1, -2} -> 所以子字符串是无效的。
了解了上面的思路后,我们就可以有解决问题的办法了。
根据所有这些要求,我们可以使用Segment tree,它为您提供 O(log n) 更新和 O(log n) 检索。
伪代码
SegmentTree tree;
Initialize the tree with original sequence
for each query in the tree
if( query type is update)
if(change from ) to ()
increase all value by 2 from range index to n
else if(change from ( to ) )
decrease all value by 2 from range index to n
else
int min = tree.getMinimumValueInRange(u, v)
int notInSubstring = tree.getMinimumValueInRange(u - 1, u - 1)
if(min - notInSubstring < 0)
print Invalid
else if( length of substring is not even)
print Invalid
else if( tree.getMinimumValueInRange(v, v) != notInSubstring)//Number of open and close brackets are not equaled.
print Invalid