正题
移除无效的括号
给你一个由 '('、')' 和小写字母组成的字符串 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 = "))(("
输出: ""
解释: 空字符串也是有效的
示例 4:
输入: s = "(a(b(c)d)"
输出: "a(b(c)d)"
解析:
本题思路来源于之前的一篇文章:判断有效括号
该解总体思路是通过栈的方式去判断是否能够将左右括号一一对应,如果可以则遍历结束后栈中没有任何元素。要应用在本题中,我们只需要记录非有效括号的下标,然后将其在原数组中删除即可。
主要逻辑
-
遍历字符串,仅仅针对
()两个括号进行逻辑判断,其余字符忽略。 -
建立栈空间,对遍历的
()进行push,pop操作。 -
当出现
(时,直接push进栈 -
当出现
)时,有两种情况4.1. 前一个是
(说明该有括号和左括号可以组成闭合,都是有效括号,那么 该)不必压入栈中,并且将(弹出4.2. 前一个也是
)说明该括号必然无效,因为前一个)都没有匹配了,当前这个更匹配不到。则将该字符压入栈中。 -
将栈中的元素下标遍历,从数组中删除对应下标。
主要代码:
/**
* @param {string} s
* @return {string}
*/
var minRemoveToMakeValid = function(s) {
let stack = []
for(let index = 0 ; index < s.length ; index++) {
const char = s[index]
// 第一个出现的必然进栈
if (stack.length === 0 && (char === '(' || char === ')')) {
stack.push({char, index})
continue
}
if (char === ')') {
if (stack[stack.length - 1].char === '(') {
stack.pop()
} else {
stack.push({char, index})
}
} else if (char === '(') {
stack.push({char, index})
}
}
stack = stack.map(i => {return i.index})
let count = 0
s = s.split('')
while(count < stack.length) {
s.splice(stack[count] - count, 1)
count++
}
return s.join('')
};