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

344 阅读2分钟

题目介绍

力扣921题:leetcode-cn.com/problems/mi…

给定一个由 '(' 和 ')' 括号组成的字符串 S,我们需要添加最少的括号( '(' 或是 ')',可以在任何位置),以使得到的括号字符串有效。

从形式上讲,只有满足下面几点之一,括号字符串才是有效的:

它是一个空字符串,或者它可以被写成 AB (A 与 B 连接), 其中 A 和 B 都是有效字符串,或者它可以被写作 (A),其中 A 是有效字符串。给定一个括号字符串,返回为使结果字符串有效而必须添加的最少括号数。

image.png

分析

这道题挺简单的,咱们直接看代码,如下:

public int minAddToMakeValid(String s) {
    // need 变量记录右括号的需求量
    int need = 0;
    // res 记录插入次数
    int res = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '(') {
            // 对右括号的需求 + 1
            need++;
        }

        if (s.charAt(i) == ')') {
            // 对右括号的需求 - 1
            need--;

            if (need == -1) {
                need = 0;
                // 需插入一个左括号
                res++;
            }
        }
    }
    return need + res;
}

这段代码就是最终解法,核心思路是以左括号为基准,通过维护对右括号的需求数need,来计算最小的插入次数。需要注意两个地方:

1、当need == -1的时候意味着什么

因为只有遇到右括号)的时候才会need--need == -1意味着右括号太多了,所以需要插入左括号。

比如说s = "))"这种情况,需要插入 2 个左括号,使得s变成"()()",才是一个合法括号串。

2、算法为什么返回res + need

因为res记录的左括号的插入次数,need记录了右括号的需求,当 for 循环结束后,若need不为 0,那么就意味着右括号还不够,需要插入。

比如说s = "))("这种情况,插入 2 个左括号之后,还要再插入 1 个右括号,使得s变成"()()()",才是一个合法括号串。