给你一个由 ‘(’、‘)’ 和小写字母组成的字符串 s。你需要从字符串中删除最少数目的 ‘(’ 或者 ‘)’ (可以删除任意位置的括号),使得剩下的「括号字符串」有效。
这里还是栈的使用。但是因为需要从s
中剔除无效的字符,所以需要记住无效字符的位置。
-
扫描字符串
- 如果是
(
,推入栈中 - 如果是
)
, 则判断栈顶是否是(
,如果是有效成对的括号,那么栈顶肯定是(
,将栈顶字符pop
出,否则不成对,将当前字符以及他的索引push
进栈中作为无效字符保存 - 如果是一般字符,不做处理
- 如果是
-
扫描一次之后,栈中保存当前所有无效的字符机及其位置,通过位置索引,将所有字符过滤掉
const minRemoveToMakeValid = function(s) {
const stack = []
for(let i = 0; i < s.length; i++) {
if (s[i] === '(') {
stack.push({ idx: i, char: s[i] })
} else if (s[i] === ')') {
// 如果成对出现表明是有效的"()"
if (stack.length > 0 && stack[stack.length - 1].char === '(') {
stack.pop()
} else {
// 无效字符,收集起来
stack.push({ idx: i, char: s[i] })
}
}
}
let count = 0
stack.forEach( item =>{
s = spliteStr(s, item.idx - count++)
})
return s
};
// 剔除字符串s, 索引为index的字符
function spliteStr(s, i) {
// 特殊处理第一位和最后一位
if (i === 0) {
return s.slice(1)
} else if (i === s.length - 1) {
return s.slice(0, -1)
} else {
return s.slice(0, i) + s.slice(i + 1)
}
}
- 时间复杂度: O(n), n为字符串长度,最坏情况为2n
- 空间复杂度: O(n)