「这是我参与11月更文挑战的第 19 天,活动详情查看:2021最后一次更文挑战」
题目来源:leetcode 1249. 移除无效的括号 JavaScript版
题目
给你一个由 '('、')' 和小写字母组成的字符串 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)"
提示:
1 <= s.length <= 10^5
s[i] 可能是 '('、')' 或英文小写字母
题解
提出问题
- 会有字母应该如何删除括号?
分析
- 从题目中可以看处,字符串
s
值包含'(',')'
与字母 - 由于括号闭合顺序是先入后出与栈数据结构一样,因此使用栈数据结构来解决问题,定义
leftDel
,rightDel
分别存放当前左括号'('
,右括号')'
- 通过
for
遍历字符串s
- 当遇到左括号时,通过
push
入栈leftDel
- 当与到右括号时, 如果当前存在
'('
,从删除列表里面删除,通过pop
出栈leftDel
- 否则
')'
是多余的,push
入栈rightDel
- 最后只需要按照
leftDel
,rightDel
里存在下标删除对应的字符 - 假设字符串
s
为(a(b(c)d)
- 开始遍历字符串
s
,此时第一位为左括号(
,因此通过push
入栈leftDel
- 重复执行上述操作,当遇到左括号
(
,因此通过push
入栈leftDel
- 重复执行上述操作,当遇到左括号
(
,因此通过push
入栈leftDel
- 当遇到左括号
)
,判断leftDel
是否为空,为空的话push
入栈rightDel
,否则pop
出栈leftDel
- 重复执行上述操作,当遇到左括号
)
,判断leftDel
是否为空,为空的话push
入栈rightDel
,否则pop
出栈leftDel
遍历完字符串s
时,删除leftDel
,rightDel
里下标对应的元素,并返回处理后的字符串
代码实现
/**
* @param {string} s
* @return {string}
*/
var minRemoveToMakeValid = function(s) {
let n = s.length
let leftDel = []
let rightDel = []
for(let i = 0; i < n;i++){
const char = s[i]
if(char === "("){
leftDel.push(i)
}else if(char === ")"){
if(leftDel.length > 0){
leftDel.pop()
}else{
rightDel.push(i)
}
}
}
// 根据记录删除无效的括号
let res = [...s]
let filter = leftDel.concat(rightDel)
let l = filter.length
for(let i = 0;i < l; i++){
res[filter[i]] = ""
}
return res.join("")
};
复制代码