🌈【LeetCode 1541. 平衡括号字符串的最少插入次数 】- JavaScript(栈模拟)

279 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【LeetCode 1541. 平衡括号字符串的最少插入次数 】- JavaScript(栈模拟)

题目描述

给你一个括号字符串 s ,它只包含字符 '(' 和 ')' 。一个括号字符串被称为平衡的当它满足:

  • 任何左括号 '(' 必须对应两个连续的右括号 '))' 。

  • 左括号 '(' 必须在对应的连续两个右括号 '))' 之前。

比方说 "())", "())(())))" 和 "(())())))" 都是平衡的, ")()", "()))" 和 "(()))" 都是不平衡的。

你可以在任意位置插入字符 '(' 和 ')' 使字符串平衡。

请你返回让 s 平衡的最少插入次数。

示例 1:

输入:s = "(()))" 输出:1 解释:第二个左括号有与之匹配的两个右括号,但是第一个左括号只有一个右括号。我们需要在字符串结尾额外增加一个 ')' 使字符串变成平衡字符串 "(())))" 。

思路分析:

栈的思路:依旧是对字符串进行遍历,从右往左遍历字符串,通过设置count变量来记录右括号‘)’的数量,如果遇到左括号时就进行count变量-2,但是要注意这几点:

  • 对遍历的第一个括号时操作数时,进行特判。
  • 遍历时遇到到左括号时且当右边落单右括号时,进行的处理是‘()))’
  • 遍历时遇到到左括号时对右边夹缝中右括号的处理是‘()(’
  • 左括号对应的右括号一定要是偶数,即左括号必须在对应的连续两个右括号之前
  • 如果为奇数, 表明此时需要插入一个右括号,如果左括号不足,那么补1;

这个题有个坑就是再出现一组连续括号的后,开始我以为是要将这组括号都匹配完,最后发现只需要匹配完右括号,左括号可以向后保留。

var minInsertions = function(s) {
    let len = s.length,
        stack = [],
        res = 0
    for(let i = 0; i < len; i++) {
        if(s[i] == '(') {
            stack.push('(')
            continue
        }

        if(i + 1 == len) {
            if(stack.length == 0) res += 2
            else {
                res++
                stack.pop()
            }
        }else {
            if(s[i+1] == ')') {
                if(stack.length == 0) res++
                else stack.pop()
                i++
            }else {
                if(stack.length == 0) res += 2
                else {
                    res++
                    stack.pop()
                }
            }
        }
    }

    res += stack.length * 2
    return res
};

思考

其实这个题目用栈模拟是最后的方法,当前其他方法也是可以做的,但是栈的方式更容易的理解和处理,时间复杂度也很低。虽然用栈的,但是可以正向模拟,也可以逆向模拟,即既可以埋点count数量进行减减,或者模拟操作数据正向增加。


感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤