括号序列问题

括号序列问题

问题集合

括号序列与前缀和

()分别看成是 1 1 1 − 1 -1 1,得到一个数字序列,对这个数字序列做前缀和,可以通过这个前缀和判断其任意子序列是否合法。

子序列合法等价于 p s u m [ r ] − p s u m [ l − 1 ] = 0 psum[r] - psum[l - 1] = 0 psum[r]psum[l1]=0并且 min ⁡ i = l r p s u m [ i ] − p s u m [ l − 1 ] ≥ 0 \min_{i=l}^r psum[i] - psum[l - 1] \geq 0 mini=lrpsum[i]psum[l1]0。其后者可以使用RMQ解决。

在一个合法的序列中任意插入一对(),其序列仍合法,删除也同理。证明:在插入)势必会插入(,其)前一个前缀和即使为 0 0 0,在插入)后也会为 1 1 1,所有不会出现负的前缀和。此外插入一对(),对其整体和不改变。

删除任意如()()()()...的子序列的最小步数等价于最大前缀和。

CF1556E


LeetCode 678

这个题还可以时候前缀和+贪心的方式进行处理。

我们维护两个变量,一个为 m x mx mx,另一个为 m i mi mi,计算方法如下,遇到‘*’的时候,分别看成左右括号,变量分别加一减一。

for (int i = 0; i < s.size(); i++)
{
    if (s[i] == '(')
    {
        mx++;
        mi++;
    }
    else if (s[i] == ')')
    {
        mx--;
        mi--;
    }
    else
    {
        mx++;
        mi--;
    }
    mi = max(0, mi);

    if (mx < 0)
        return false;
}

我们考虑 m i mi mi为负的时候,考虑撤回一个’*‘使其不让他成为’)’,如果均撤销,那么就让它变成’(’,如果可用’*‘不够用的时候,即’*‘全变为’('也改变不了 m i mi mi为负数的情况,即 m x < 0 mx < 0 mx<0,则返回false。最后查看 m i mi mi是否为0即可。

括号序列和区间DP

括号序列是显然的区间,故可以使用区间DP求解。

例如:

CF1556C

括号序列和栈

括号序列和栈是一对对应的数据结构,其多数问题均可以使用栈解决。

  • 合法的括号序列计数:Catalan数列
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值