技术岗位 · Coding

最少插入括号使序列合法:贪心修复负前缀

只插入、不删除、不重排,最后补足未闭合左括号。

题目重点:只插入、不删除、不重排,最后补足未闭合左括号。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 输入仅(和),要求通常的括号匹配:任意前缀左数≥右数,最终相等。
  • 每次插入任意单个括号,返回最少数量。

解题路线

  1. 维护未匹配左括号balance。遇(加1;遇)且balance>0则配掉一个。
  2. 遇)且balance=0,原前缀无法靠未来括号修复,必须在它前面插一个(,因此该操作为必要下界。
  3. 结束剩balance个左括号必须各补一个),同样必要。算法只做这些必要修复,因此达到下界。

手动走一遍

输入())(:第三个)需要补(,尾部(需要补),总2。)))需要前置三个(;空串0。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def min_insertions(s):
    balance = inserted = 0
    for c in s:
        if c == '(':
            balance += 1
        elif c == ')':
            if balance:
                balance -= 1
            else:
                inserted += 1
        else:
            raise ValueError("parentheses only")
    return inserted + balance

复杂度

O(n)时间、O(1)空间。生成结果字符串另需O(n+answer)。

易错点与追问

容易失分的边界

  • 不要遇到无匹配)就把balance减到负数然后只看最终绝对值。
  • 若规则一个(须配两个)),状态和最优修复不同。

继续深挖

  • 若插入/删除费用不同,贪心的必要性还成立吗?
  • 如何返回一种实际修复字符串及插入位置?
✓已复制微信号!