持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
[921] 使括号有效的最少添加
原题链接:
921. 使括号有效的最少添加
示例 1:
输入: s = "())"
输出: 1
示例 2:
输入: s = "((("
输出: 3
解题思路
由题,每个左括号必须对应一个右括号,而且左括号必须在对应的右括号之前。我们可以用计数法来保存左括号和右括号的出现次数,最终得出使括号有效的最少添加的值:
我们可以从左到右遍历字符串,在遍历过程中维护左、右括号的个数以及匹配成功的次数。
如果遇到左括号,则将左括号的个数加 1。
如果遇到右括号,则需要和前面的左括号进行匹配,具体做法如下:
- 左括号和右括号匹配,对应的计数指示器做加减,然后做之后的匹配
- 如果当前
s[i] === '('(左括号),左括号计数器left+1 - 如果当前
s[i] === ')'(右括号),则需要:- 当
left > 0, 那么右括号就有一个可以与其匹配上,就是合法字符串,所以我们就可以将左括号的个数减 1 (表示牵手成功) - 当
left == 0, 那就说目前没有左括号可以匹配,那么 右括号单身狗+1 (right+1),需要后来补充
- 当
- 如果当前
- 最后答案,就是未匹配上的
left和未匹配上的right的相加之和
步骤一 设置 对应计数器
var minAddToMakeValid = function(s) {
let left = 0 // 未匹配上的左括号
let right = 0 // 为匹配上的右括号
}
步骤二 维护左、右括号的个数以及匹配成功的次数
for(let i = 0; i<s.length; i++) {
if(s[i] === '('){
left++
}else{
if(left > 0){
left--
}else{
right++
}
}
}
完整代码
var minAddToMakeValid = function(s) {
let left = 0 // 未匹配上的左括号
let right = 0 // 为匹配上的右括号
for(let i = 0; i<s.length; i++) {
if(s[i] === '('){
left++
}else{
if(left > 0){
left--
}else{
right++
}
}
}
return right + left
};
无论是哪种添加的情况,都是在遇到括号无法进行匹配的情况下才进行添加,因此上述做法得到的添加次数是最少的。