AI刷题-括号补全问题 | 豆包MarsCode AI刷题

75 阅读3分钟
问题描述

小R有一个括号字符串s,他想知道这个字符串是否是有效的。一个括号字符串如果满足以下条件之一,则是有效的!

1.它是一个空字符串;

2.它可以写成两个有效字符串的连接形式,即 AB,3. 它可以写成(A) 的形式,其中 A是有效字符串。在每次操作中,小R可以在字符串的任意位置插入一个括号。你需要帮小R计算出,最少需要插入多少个括号才能使括号字符串s有效,例如:当s="())"时,小R需要插入一个左括号使字符串有效,结果为 1。

测试样例

样例1:

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

样例2:

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

样例3:

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

样例4:

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

解题思路
  1. 初始化变量
    • left:用于跟踪未匹配的左括号数量。每当我们遇到一个左括号,这个数量就会增加;每当遇到一个右括号且没有匹配的左括号,这个数量就会减少。
    • to_insert:用于记录需要插入的括号数量。每当我们遇到一个右括号而没有足够的左括号与之匹配时,我们就需要插入一个左括号,并将to_insert加1。
  1. 遍历字符串
    • 对于字符串中的每个字符,如果是左括号(,我们增加left的计数,因为现在我们有一个未匹配的左括号。
    • 如果是右括号),我们尝试减少left的计数,这意味着我们尝试将这个右括号与一个未匹配的左括号匹配。如果left变为负数,这意味着没有足够的左括号与当前的右括号匹配,因此我们需要插入一个左括号来匹配这个右括号,并将to_insert加1。同时,我们将left重置为0,因为插入的左括号已经与当前的右括号匹配了。
  1. 处理剩余的左括号
    • 遍历结束后,left中可能还有剩余的未匹配的左括号。对于每个未匹配的左括号,我们需要插入一个右括号来与之匹配,因此我们将to_insert增加left的值。
  1. 返回结果
    • 最后,to_insert包含了我们需要插入的括号的总数,这就是使得原始字符串有效的最小插入次数。
示例

示例输入 s = "())" 来说明这个过程:

  1. 初始化 left = 0to_insert = 0
  2. 遍历字符串:
    • 遇到第一个右括号)left = 0 - 1 = -1(没有匹配的左括号,需要插入一个左括号),to_insert = 1
    • 遇到第二个右括号)left = -1 - 1 = -2(没有匹配的左括号,需要再插入一个左括号),to_insert = 2
  1. 遍历结束,left = -2(有两个未匹配的右括号),这意味着我们需要再插入两个右括号来匹配这两个未匹配的左括号。
  2. 总的插入次数是 to_insert = 2(为右括号插入的左括号)加上 abs(left) = 2(为左括号插入的右括号),所以结果是 2 + 2 = 4

因此,最少需要插入4个括号来使字符串 s = "())" 有效。

代码实现
def solution(s: str) -> int:
    left = 0  # 未匹配的左括号数量
    to_insert = 0  # 需要插入的括号数量
    for char in s:
        if char == '(':
            left += 1
        elif char == ')':
            left -= 1
            if left < 0:
                # 没有匹配的左括号,需要插入一个左括号
                to_insert += 1
                left = 0  # 插入左括号后,重置未匹配的左括号数量
    return to_insert + abs(left)  # 未匹配的左括号需要插入右括号

if __name__ == '__main__':
    print(solution("())") == 1)
    print(solution("(((") == 3)
    print(solution("()") == 0)
    print(solution("()))((") == 4)