学习笔记:括号补全问题
问题描述:
给定一个包含 ( 和 ) 的括号字符串 s,我们的目标是计算出最少需要插入多少个括号,才能使得这个字符串变得有效。
一个有效的括号字符串需要满足以下条件:
- 括号能够成对出现并且嵌套正确。
- 例如
(),()(),(())都是有效的。
我们需要求解的是最少的插入括号数目,使得原字符串变为有效字符串。
示例:
- 输入:
"())"输出:1解释:只需要插入一个左括号,使得字符串变为()。 - 输入:
"((("输出:3解释:需要插入三个右括号,使得字符串变为((()))。 - 输入:
"()"输出:0解释:字符串已经有效,不需要插入任何括号。 - 输入:
"()))(("输出:4解释:需要插入四个括号使字符串变为(())()。
解题思路:
要解决这个问题,关键在于理解括号的配对规则:
- 左括号
(必须有对应的右括号)来闭合。 - 右括号
)必须在对应的左括号(后面出现。
我们可以通过两个计数器来模拟处理这个问题:
left_needed:表示缺失的左括号数量。right_needed:表示缺失的右括号数量。
解决过程:
-
遍历字符串中的每个字符:
-
如果是左括号
(,则假设这个左括号可以等待一个右括号来匹配,因此增加left_needed。 -
如果是右括号
),则检查是否有未匹配的左括号:- 如果有匹配的左括号(
left_needed > 0),则减少left_needed,表示这个右括号匹配了一个左括号。 - 如果没有匹配的左括号(
left_needed == 0),则说明我们缺少一个左括号,增加right_needed。
- 如果有匹配的左括号(
-
-
最终,
left_needed和right_needed的和就是最少需要插入的括号数。
代码实现:
python
复制代码
def solution(s: str) -> int:
left_needed = 0 # 需要的左括号
right_needed = 0 # 需要的右括号
for char in s:
if char == '(': # 遇到左括号
left_needed += 1
elif char == ')': # 遇到右括号
if left_needed > 0: # 如果有多余的左括号
left_needed -= 1 # 匹配一个左括号
else:
right_needed += 1 # 否则需要插入一个左括号
return left_needed + right_needed # 左括号和右括号的缺失总和就是需要插入的括号数
代码解析:
-
left_needed:记录当前缺少的左括号数量。每当遇到一个左括号(,就增加left_needed。 -
right_needed:记录当前缺少的右括号数量。每当遇到一个右括号),我们先检查是否有多余的左括号可以与之配对:- 如果有多余的左括号,可以进行匹配,减少
left_needed。 - 如果没有多余的左括号,则增加
right_needed,表示我们缺少一个左括号,需要插入。
- 如果有多余的左括号,可以进行匹配,减少
最后,返回 left_needed + right_needed 即可,它表示要插入的括号数。
示例运行:
示例 1:
python
复制代码
s = "())"
print(solution(s)) # 输出: 1
- 插入一个左括号,变成
()。
示例 2:
python
复制代码
s = "((("
print(solution(s)) # 输出: 3
- 插入三个右括号,变成
((()))。
示例 3:
python
复制代码
s = "()"
print(solution(s)) # 输出: 0
- 字符串已经有效,无需插入括号。
示例 4:
python
复制代码
s = "()))(("
print(solution(s)) # 输出: 4
- 插入四个括号,变成
(())()。
时间复杂度:
- 时间复杂度是 O(n),其中
n是字符串s的长度。我们只需要遍历字符串一次,因此时间复杂度是线性的。
空间复杂度:
- 空间复杂度是 O(1),因为我们只用了常数的空间来存储
left_needed和right_needed。
小结:
本题利用两个计数器 left_needed 和 right_needed 来跟踪缺失的括号数量,并根据遍历结果计算出最少插入括号的数目。这个方法简单且高效,时间复杂度为 O(n),适用于较大的输入。
希望这篇笔记能帮助你更好地理解并解决括号配对问题!