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

String 通过对字符串执行某些操作来检查括号字符串是否平衡,string,algorithm,data-structures,segment-tree,range-query,String,Algorithm,Data Structures,Segment Tree,Range Query,给定括号字符串,我们必须执行两种操作: 翻转-将第i个括号更改为相反的括号(左->右,右->左) 检查-字符串是否为平衡圆括号表达式 字符串的最大长度为30000 要执行的操作数量为最大值 十万 应该使用什么样的数据结构来解决此类问题 段树是合适的数据结构吗 如果是,应如何使用 范例 字符串=()(( 操作次数=4 翻转4{新字符串为()()} 检查{字符串已平衡} 翻转2{新字符串变为((()} 检查{字符串不平衡} 一个检查字符串是否平衡的函数很容易实现。单步遍历字符串,如果满足“(“字符满

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

  • 翻转-将第i个括号更改为相反的括号(左->右,右->左)
  • 检查-字符串是否为平衡圆括号表达式
  • 字符串的最大长度为30000

    要执行的操作数量为最大值 十万

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

    段树是合适的数据结构吗

    如果是,应如何使用

    范例

    字符串=()((

    操作次数=4

  • 翻转4{新字符串为()()}
  • 检查{字符串已平衡}
  • 翻转2{新字符串变为((()}
  • 检查{字符串不平衡}

  • 一个检查字符串是否平衡的函数很容易实现。单步遍历字符串,如果满足“(“字符满足,则递减”)”条件,则递增一个零初始化值。如果结果为0,并且在运行过程中从未低于0,则该字符串是平衡的。 在字符串的第n个位置翻转括号很简单

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

    功能检查平衡(str){
    var-res=0;
    对于(i=0;i=str.length)返回str;
    返回str[i]==“(”?
    str.substr(0,i)+“”+str.substr(i+1):
    str.substr(0,i)+“(“+str.substr(i+1));
    }
    //初始字符串
    var curr=“()(())”;
    //待执行的操作
    var-ops=40;
    log('初始字符串:'+curr+'+checkbalancess(curr));
    console.log('operations:'+ops);
    console.log('start');
    var ii;
    var-chartoflip;
    对于(ii=0;ii让每个
    +1
    )和每个
    -1
    。如果整个字符串的和为零,且每个范围的和为非负,则括号字符串是平衡的

    让我们为子串定义两个函数,
    sum
    min
    sum
    是显而易见的,而
    min(i,j)
    定义为所有
    sum(i,k)
    中的最小值,其中
    k=0和
    root.sum==0,因此
    O(1)


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

    可能误解了这个问题,但您是在寻找一种算法,该算法给定一个不平衡的字符串,将其转换为一个翻转次数尽可能少的平衡字符串?还是您只是在寻找一种检查字符串是否平衡的方法?@user2464424给定的字符串可能是平衡/不平衡的?我正在寻找的算法向前有两个操作翻转和检查,可以有任意数量的翻转或检查(最多100000次)对于每个检查,我必须确定整个字符串是否平衡,对于每个翻转,我必须翻转第I个字符。为什么在检查字符串之前就开始翻转?为什么在检查通过后继续?如何知道要翻转哪个字符?检查返回真/假还是第一个问题的位置?仍然不清楚,您是(1)在寻找函数
    flip
    check
    的实现,还是(2)在给定这两个函数的情况下,可以“修复”不平衡的括号字符串的算法,还是(3)两者都有?
    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');
    
    sum(i,k) = sum(i,j) + sum(j+1, k)
    
    min(i,k) = MIN( min(i,j), sum(i,j) + min(j + 1, k) )