在问 · 算法题解

921. 使括号有效的最少添加

题目描述

输入字符串 s,只由 '(' 和 ')' 组成。

有效括号串的定义:空串有效;两个有效串拼接后有效;在一个有效串外面套一对 () 后也有效。

每次操作可以在 s 的任意位置插入一个 '(' 或一个 ')'。返回让 s 变成有效括号串所需的最少插入次数。

示例 1
输入:s = "())"
输出:1

解释:末尾多出一个 ),补一个 ( 即可。

示例 2
输入:s = "((("
输出:3

解释:三个 ( 都没有配对,需要补三个 )。

数据范围

  • 1 <= s.length <= 1000
  • s 中只有 '(' 和 ')' 两种字符。

解题思路

用一个计数器 bal 代替栈,记录还没配对的左括号数。遇到 ( 就 bal+1;遇到 ) 时若有未配对的左括号就消掉一个,否则这个 ) 无论如何都缺一个左括号,ans+1。扫描结束后剩下的 bal 个左括号各缺一个右括号,答案是 ans + bal。

为什么正确

扫描完前缀后,bal 是前缀中未配对的 ( 个数,ans 是前缀中必然无法配对的 ) 个数。

复杂度分析

时间 O(n),额外空间 O(1)。

易错点

只统计左右括号数量之差是错的:")(" 两种括号数量相等,答案却是 2。必须按顺序配对,右括号只能和它左边的左括号配对。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def minAddToMakeValid(self, s: str) -> int:
        ans = bal = 0
        for c in s:
            if c == '(':
                bal += 1
            elif bal > 0:
                bal -= 1
            else:
                ans += 1
        return ans + bal

载入编辑器,自己跑一遍 →

栈与堆 专题的其他题目

查看 栈与堆 全部题目 →