题目介绍
给你一个由 '('、')' 和小写字母组成的字符串 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^5s[i]可能是'('、')'或英文小写字母 leetcode-1249 移除无效的括号
b站视频
解题思路
这道题我们可以使用标志法,当遇到 '(' 时,将标志位 +1,当遇到 ')' 且标志位大于 0 时,将标志位 -1,如果标志位为 0,说明该位置的 ')' 非法,需要将该 ')' 移除
执行完上述过程之后,我们已经将多余的 ')' 全部移除了,这时候还可能存在多余的 '(',有两种方法可以移除非法的 '(':
- 反向执行上述步骤,将多余的 '(' 移除
- 从右往左,'(' 比 ')' 多了几个,我们就删除几个 '('
步骤:
- 定义一个空数组
arr和标记位sign, 遍历s字符串 - 遇到
'('或者 小写字母时,将其放到数组中,如果是'(',将sign+1 - 如果遇到
')'且sign > 0,说明')'合法,将其放到数组中,同时sign-1;如果sign <= 0,说明该位置不合法,直接跳过 - 执行完以上步骤,如果
sign为0,表示'('和')'一样多,直接返回arr拼接成字符串即可;如果sign不为0,sign为多少则表示'('比')'多了几个,直接从右往左删除sign个'('即可,再返回arr拼接成字符串
解题代码
var minRemoveToMakeValid = function(s) {
const arr = []
let sign = 0
for (let i = 0; i < s.length; i++) {
if (s[i] !== ')') {
if (s[i] === '(') sign++
arr.push(s[i])
} else if (sign > 0) {
sign--
arr.push(s[i])
}
}
if (!sign) return arr.join('')
for (let i = 0; i < sign; i++) {
arr.splice(arr.lastIndexOf('('), 1)
}
return arr.join('')
};