1541. 平衡括号字符串的最少插入次数

目录

题目解析 | 平衡括号字符串(每个左括号对应两个连续右括号)最少插入次数

题目描述

解题分析

解题思路

代码实现(Python)

复杂度分析

详细示例说明

代码对比与错误分析

小结


题目解析 | 平衡括号字符串(每个左括号对应两个连续右括号)最少插入次数

题目描述

给定一个只包含字符 '('')' 的字符串 s,定义如下的平衡括号字符串规则:

  • 每个左括号 '(' 必须对应连续的两个右括号 '))'
  • 左括号必须在对应的两个连续右括号之前。

举例来说:

  • 平衡的字符串示例:
    • "())"(一个左括号,后面紧跟连续两个右括号)
    • "())(())))"
    • "(())())))"
  • 不平衡的字符串示例:
    • ")()"(第一个字符是右括号,左括号没有匹配)
    • "()))"
    • "(()))"(虽然括号数量相符,但不符合连续两个右括号的规则)

你可以在字符串中任意位置插入 '('')',使字符串变为平衡状态。请返回使字符串平衡所需的最少插入次数。


解题分析

这道题本质是括号匹配问题的变体,但由于“每个左括号对应连续两个右括号”的特殊规则,使得传统的单个右括号匹配逻辑不适用。

主要难点是:

  • 每个 '(' 需要连续 两个')' 来匹配。
  • 右括号必须连续成对出现,不能分开计算。
  • 可以插入括号修正不平衡,要求最少插入次数。

为了设计有效的算法,我们需要清楚维护当前字符串中“还需要多少个右括号”来匹配已出现的左括号。


解题思路

定义两个变量:

  • need:当前还需要多少个右括号 ')' 来匹配之前的左括号 '('
  • res:记录插入括号的次数。

遍历字符串字符,逐步更新 needres

  1. 遇到 '('
    • 首先检查 need 是否是奇数。
      • 如果是奇数,说明之前的右括号不完整(单数个右括号),需要插入一个右括号 ')' 来补全。
      • 插入后,res += 1need -= 1
    • 由于每个 '(' 需要两个连续的 ')',所以 need += 2
  1. 遇到 ')'
    • 每遇到一个右括号,need -= 1,消耗一个右括号的需求。
    • 如果此时 need < 0,说明出现了多余的右括号,必须先插入一个 '(' 来匹配。
      • 插入一个 '('res += 1,这时该 '(' 需要两个右括号,还使用了当前的一个 ')',所以 need = 1
  1. 遍历结束后:
    • 如果 need > 0,表示还有未匹配的右括号需求,需要插入相应数量的 ')'
    • 最终结果是 res + need

代码实现(Python)

class Solution:
    def minInsertions(self, s: str) -> int:
        res = 0
        need = 0  # 需要的右括号数量

        for c in s:
            if c == '(':
                # 如果 need 是奇数,先插入一个 ')' 补全之前的不完整匹配
                if need % 2 == 1:
                    res += 1
                    need -= 1
                # 每个 '(' 需要两个连续 ')'
                need += 2
            else:  # c == ')'
                need -= 1
                if need < 0:
                    # 右括号过多,需要插入 '(' 来匹配
                    res += 1
                    need = 1
        # 遍历结束,插入剩余的 ')' 来完成匹配
        return res + need

复杂度分析

  • 时间复杂度:O(n),遍历字符串一次。
  • 空间复杂度:O(1),只用常数额外空间。

详细示例说明

以输入 s = "(()))" 为例:

位置

字符

说明

need

res

0

'('

need 是0(偶数),不插入,need += 2

2

0

1

'('

need 是2(偶数),不插入,need += 2

4

0

2

')'

need -= 1

3

0

3

')'

need -= 1

2

0

4

')'

need -= 1 → 1

1

0

遍历结束后,need = 1,表示还需要插入1个 ')' 才能匹配所有 '('

最终插入次数 res + need = 0 + 1 = 1


代码对比与错误分析

之前尝试的版本错误原因:

  • 没有处理每个 '(' 需要两个连续右括号的细节。
  • 处理右括号消耗时,未考虑奇数个右括号的插入需求。

这版代码改正了上述细节,并且逻辑清晰,适用于所有测试用例。


小结

这道题目的核心在于:

  • 理解“一个左括号对应连续两个右括号”的匹配关系。
  • 用变量 need 追踪当前还需多少右括号。
  • 插入括号时处理不匹配的奇数情况。

利用贪心策略,一次遍历即可完成计算,时间和空间都高效。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值