📌  相关文章
📜  通过删除形成有效括号的子序列来最小化给定字符串的长度(1)

📅  最后修改于: 2023-12-03 15:12:23.832000             🧑  作者: Mango

最小化字符串长度 - 删除无效括号

在编程过程中,我们时常会遇到处理字符串的情境,而对于括号的匹配问题,是其中比较常见的一个问题。本题目要求通过删除无效括号,最小化给定字符串的长度。

问题描述

我们有一个包含括号的字符串,需要通过删除其中的一些字符,使其成为一个有效的括号序列,并且最小化这个序列的长度。

解题思路
Step 1: 判断括号是否有效

对于一个有效的括号序列,其左右括号的数量应该是相等的,且每个左括号都有一个相应的右括号与之匹配。因此,我们可以通过栈来进行括号的匹配判断:

遍历整个字符串,对于每个字符:

  • 如果是左括号,则将其加入栈中;

  • 如果是右括号:

    • 如果栈为空,则说明当前括号字符无法与之前任何一个左括号匹配,该括号不属于有效括号序列,需要将其删除;
    • 如果栈不为空,则弹出栈顶的左括号,与当前右括号进行匹配;

最后,如果栈为空,则说明整个序列是一个有效的括号序列。

Step 2: 找到需要删除的无效括号序列

上述栈的匹配过程中,对于不能匹配的右括号,需要将其删除,以将该字符从序列中删除,如:“)(a+b)+” 中的右括号:

  • 对于“)”,没有与之匹配的左括号,应该删除;

对于不能匹配的左括号,也需要将其删除,如:“(a+b)+(c+d)*e+(f+)”中的左括号:

  • 对于“(”,没有与之匹配的右括号,应该删除。
Step 3: 组合成有效括号序列

根据上述步骤,我们可以得到一个最小化的有效括号序列,这个序列是由原序列删去无效括号后的结果。

代码实现

下面是一个简单的 Python 代码实现:

def remove_invalid_parentheses(s: str) -> str:
    # 判断括号是否有效
    def is_valid(s):
        stack = []
        for ch in s:
            if ch == '(':
                stack.append(ch)
            elif ch == ')':
                if not stack:
                    return False
                stack.pop()
        return not stack

    # dfs 查找无效括号
    def dfs(s, start, left_count, right_count, left_remove, right_remove, path, res):
        if start == len(s):
            if left_count == right_count and is_valid(path):
                res.add(path)
                return
        elif left_count >= right_count:
            if s[start] == '(' and left_remove > 0:
                dfs(s, start + 1, left_count, right_count, left_remove - 1, right_remove, path, res)
            elif s[start] == ')' and right_remove > 0:
                dfs(s, start + 1, left_count, right_count, left_remove, right_remove - 1, path, res)

        if s[start] == '(':
            dfs(s, start + 1, left_count + 1, right_count, left_remove, right_remove, path + s[start], res)
        elif s[start] == ')':
            dfs(s, start + 1, left_count, right_count + 1, left_remove, right_remove, path + s[start], res)
        else:
            dfs(s, start + 1, left_count, right_count, left_remove, right_remove, path + s[start], res)

    # 删除无效括号
    left_remove, right_remove = 0, 0
    for ch in s:
        if ch == '(':
            left_remove += 1
        elif ch == ')':
            if left_remove > 0:
                left_remove -= 1
            else:
                right_remove += 1

    res = set()
    dfs(s, 0, 0, 0, left_remove, right_remove, '', res)

    # 寻找最短有效括号序列
    ans = ''
    min_len = float('inf')
    for parentheses in res:
        if len(parentheses) < min_len:
            min_len = len(parentheses)
            ans = parentheses
    return ans
总结

通过本题的练习,我们对于字符串的处理及栈的应用有了更深入的理解,同时也加强了对于递归的应用及方法掌握程度。