夯实算法-使括号有效的最少添加

108 阅读1分钟

题目:使括号有效的最少添加

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

  • 它是一个空字符串,或者
  • 它可以被写成 AB (A 与 B 连接), 其中 A 和 B 都是有效字符串,或者
  • 它可以被写作 (A),其中 A 是有效字符串。

给定一个括号字符串 s ,在每一次操作中,你都可以在字符串的任何位置插入一个括号

  • 例如,如果 s = "()))" ,你可以插入一个开始括号为 "(()))" 或结束括号为 "())))" 。 返回 为使结果字符串 s 有效而必须添加的最少括号数

示例 1:

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

示例 2:

输入: s = "((("
输出: 3

提示:

  • 1 <= s.length <= 1000
  • s 只包含 '(' 和 ')' 字符。

解题思路

有效的括号字符串中,左括号和右括号成对出现,在每对左右括号中,左括号在右括号的左边。

如果一个左括号右边没有右括号匹配,或者一个右括号左边没有左括号匹配,则需要插入相应的括号,才能使括号字符串有效。

可以使用栈存储左括号,从左到右遍历字符串 sss,计算使字符串 sss 有效的最少添加次数。对于每个字符,进行如下操作:

遇到左括号,则将左括号入栈; 遇到右括号且栈不为空,则将栈顶的左括号出栈,表示当前的右括号和栈顶的左括号匹配; 遇到右括号且栈为空,则当前的右括号没有左括号匹配,因此需要插入一个左括号,将添加次数加 111。

遍历结束之后,如果栈不为空,则栈内的每个左括号都没有右括号匹配,对于栈内的每个左括号都需要插入一个右括号,因此将添加次数加上栈内左括号个数。

最终得到的添加次数即为使字符串 sss 有效的最少添加次数。 注意上述操作中,只计算需要插入的左括号个数和右括号个数,没有考虑插入括号的位置,这是因为每一步添加可以在字符串的任意位置插入一个括号,对于每个右括号,总能在其左边找到一个位置插入左括号,对于每个左括号,总能在其右边找到一个位置插入右括号。

代码实现

public int minAddToMakeValid(String s) {
    //思路:贪心
    int ans = 0, leftCount = 0;
    int length = s.length();

    for (int i = 0; i < length; i++) {
        char c = s.charAt(i);
        if (c == '(') {
            leftCount++;
        } else {
            //判断是否有左括号可以匹配
            if (leftCount > 0) {
                leftCount--;
            } else {
                ans++;
            }
        }
    }
    //考虑类似于")("或")((("的情况
    ans += leftCount;
    return ans;
}

运行结果

Snipaste_2023-06-02_22-11-29.png

复杂度分析

  • 空间复杂度:O(1)
  • 时间复杂度:O(n)

掘金(JUEJIN) 一起分享知识, Keep Learning!