通过对字符串执行某些操作来检查括号字符串是否平衡

时间:2016-08-07 18:07:50

标签: string algorithm data-structures segment-tree range-query

给定括号字符串,我们必须做两种操作:

  1. 翻转 - 将第i个括号改为对方(左 - >右,右 - >左)
  2. 检查字符串是否为平衡括号表达式
  3. 字符串的长度最大为30000.

    最多只能进行操作 100000。

    应该使用什么样的数据结构来解决这类问题?

    Segment Tree是一个合适的数据结构吗?

    如果是,应该如何使用它?

    实施例

    string =()((

    no of operation = 4

    1. 翻转4 {new string is()()}
    2. check {string is balanced}
    3. 翻转2 {新字符串变为((()}
    4. check {string is not balanced}

2 个答案:

答案 0 :(得分:1)

让每个(+1,每)-1。如果整个字符串的总和为零,则每个范围[0, k]的总和为非负值,则平衡一串括号。

让我们为子串[i,j]summin定义两个函数。 sum显而易见,min(i,j)定义为所有sum(i,k) k <= j的最低要求。

所以

sum(i,k) = sum(i,j) + sum(j+1, k)

min(i,k) = MIN( min(i,j), sum(i,j) + min(j + 1, k) )

现在我们可以构建一个二叉树,其中叶子是+1-1,而root是整个范围[0, N-1]。对于每个节点,我们保留minsum

查询余额很明显:我们会检查root.min >= 0root.sum == 0,所以O(1)

通过更新叶节点并将更改传播到根来完成翻转。不超过log(N)+1个节点,每个更新都为O(1),因此O(logN)

答案 1 :(得分:0)

可以轻松检查字符串是否平衡的函数。单步执行字符串,如果满足“(”字符,则递增零初始化值,如果满足“()”则递减它)。如果结果为0并且在运行期间它从未低于0,则字符串是平衡的。 在字符串的第n个位置翻转括号是微不足道的。

这是javascript中的一个简单实现,它在循环中翻转字符串的随机字符,并在每次翻转后检查结果字符串的有效性。

http://jsbin.com/vagalijoca/edit?html,console

function checkbalanceness(str){
  var res = 0;
  for(i=0;i<str.length;i++) {
    str[i]=="(" ? res++ : res--;
    if (res < 0) break;
  }
  return res == 0;
}

function flipp(str, i){
  if (i >= str.length) return str;
  return str[i]=="(" ?
    str.substr(0,i) + ")" + str.substr(i+1) :
    str.substr(0,i) + "(" + str.substr(i+1) ;
}

//initial string
var curr = "()(())";
//operations to be executed
var ops = 40;

console.log('initial string: ' + curr + ' ' + checkbalanceness(curr));
console.log('operations: ' + ops);
console.log('start');
var ii;
var chartoflip;
for(ii=0;ii<ops;ii+=2){
  chartoflip = (ii/2)%(curr.length);
  curr = flipp(curr, chartoflip);
  console.log((ii) + ' - flip char ' + chartoflip + ': ' + curr);
  console.log((ii+1) + ' - checking ' + curr + ' ' + checkbalanceness(curr));
}
console.log('end');