[路飞]_程序员必刷力扣题: 1249. 移除无效的括号

172 阅读1分钟

1249. 移除无效的括号

给你一个由 '('、')' 和小写字母组成的字符串 s。

你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。

请返回任意一个合法字符串。

有效「括号字符串」应当符合以下 任意一条 要求:

  • 空字符串或只包含小写字母的字符串
  • 可以被写作 AB(A 连接 B)的字符串,其中 A 和 B 都是有效「括号字符串」
  • 可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」

示例 1:

输入:s = "lee(t(c)o)de)"
输出:"lee(t(c)o)de"
解释:"lee(t(co)de)" , "lee(t(c)ode)" 也是一个可行答案。

示例 2:

输入: s = "a)b(c)d"
输出: "ab(c)d"

示例 3:

输入: s = "))(("
输出: ""
解释: 空字符串也是有效的

提示:

  • 1 <= s.length <= 10^5
  • s[i] 可能是 '('')' 或英文小写字母

栈的思想

思路

题目虽然让我们移除无效括号,但是除了有效括号剩下就是无效括号了

因此我们需要一个stack来排除有效括号

为了后面方便删除中间的多个无效括号,我们开始就将s转为数组保存在res变量中

  • 我们将遍历遇到的括号一个一个的push到栈里,push的时候要保留当前的字符以及当前的下标位置,所以会是一个二维数组。

  • 如果')'的前面正好是'('那么匹配成功,此时直接将两个括号弹出

  • 最后stack中剩余的就是未匹配成功的需要删除的括号,其中保存着对应的下标,所以可以直接从数组中剔除

这里第一想法是直接用splice来操作,删除数组中不需要的元素,但是效率极低

后来想到因为最后还是要jion拼接起来,所以这里直接将需要删除的元素替换为空字符串‘’,效率提高了很多

var minRemoveToMakeValid = function (s) {
    var res = s.split('')
    var stack = []
    for (var i = 0; i < s.length; i++) {
        var item = s[i]
        if (item === '(') {
            stack.push([item, i])
        }
        if (item === ')') {
            if (stack.length > 0 && stack[stack.length - 1][0] === '(') {
                stack.pop()
            } else {
                stack.push([item, i])
            }
        }
    }
    for (var j = stack.length-1; j >=0 ; j--) {
        var item = stack[j]
        //res.splice(item[1],1)//超过10%
        res[item[1]] = ''//超过75%
    }
    return res.join('')
};