题目:使括号有效的最少添加
只有满足下面几点之一,括号字符串才是有效的:
- 它是一个空字符串,或者
- 它可以被写成
AB(A与B连接), 其中A和B都是有效字符串,或者 - 它可以被写作
(A),其中A是有效字符串。
给定一个括号字符串 s ,在每一次操作中,你都可以在字符串的任何位置插入一个括号
- 例如,如果
s = "()))",你可以插入一个开始括号为"(()))"或结束括号为"())))"。 返回 为使结果字符串s有效而必须添加的最少括号数。
示例 1:
输入: s = "())"
输出: 1
示例 2:
输入: s = "((("
输出: 3
提示:
1 <= s.length <= 1000s只包含'('和')'字符。
解题思路
有效的括号字符串中,左括号和右括号成对出现,在每对左右括号中,左括号在右括号的左边。
如果一个左括号右边没有右括号匹配,或者一个右括号左边没有左括号匹配,则需要插入相应的括号,才能使括号字符串有效。
可以使用栈存储左括号,从左到右遍历字符串 sss,计算使字符串 sss 有效的最少添加次数。对于每个字符,进行如下操作:
遇到左括号,则将左括号入栈; 遇到右括号且栈不为空,则将栈顶的左括号出栈,表示当前的右括号和栈顶的左括号匹配; 遇到右括号且栈为空,则当前的右括号没有左括号匹配,因此需要插入一个左括号,将添加次数加 111。
遍历结束之后,如果栈不为空,则栈内的每个左括号都没有右括号匹配,对于栈内的每个左括号都需要插入一个右括号,因此将添加次数加上栈内左括号个数。
最终得到的添加次数即为使字符串 sss 有效的最少添加次数。 注意上述操作中,只计算需要插入的左括号个数和右括号个数,没有考虑插入括号的位置,这是因为每一步添加可以在字符串的任意位置插入一个括号,对于每个右括号,总能在其左边找到一个位置插入左括号,对于每个左括号,总能在其右边找到一个位置插入右括号。
代码实现
public int minAddToMakeValid(String s) {
//思路:贪心
int ans = 0, leftCount = 0;
int length = s.length();
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (c == '(') {
leftCount++;
} else {
//判断是否有左括号可以匹配
if (leftCount > 0) {
leftCount--;
} else {
ans++;
}
}
}
//考虑类似于")("或")((("的情况
ans += leftCount;
return ans;
}
运行结果
复杂度分析
- 空间复杂度:O(1)
- 时间复杂度:O(n)
在掘金(JUEJIN) 一起分享知识, Keep Learning!