1249 移除无效的括号(栈的应用)

1. 问题描述:

给你一个由 '('、')' 和小写字母组成的字符串 s。

你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。

请返回任意一个合法字符串。

有效「括号字符串」应当符合以下 任意一条 要求:

空字符串或只包含小写字母的字符串
可以被写作 AB(A 连接 B)的字符串,其中 A 和 和 B 都是有效「括号字符串」可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」

示例 1:

输入:s = "lee(t(c)o)de)"
输出:"lee(t(c)o)de"
解释:"lee(t(co)de)" , "lee(t(c)ode)" 也是一个可行答案。

示例 2:

输入:s = "a)b(c)d"
输出:"ab(c)d"

示例 3:

输入:s = "))(("
输出:""
解释:空字符串也是有效的

示例 4:

输入:s = "(a(b(c)d)"
输出:"a(b(c)d)"

提示:

  • 1 <= s.length <= 10^5
  • s[i] 可能是 '('')' 或英文小写字母

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-remove-to-make-valid-parentheses

2. 思路分析:

① 括号匹配经常需要使用到栈,这道题目也是一样需要使用到栈的辅助作用来解决,因为使用的是python语言,在python语言中可以使用列表来模拟栈的操作,列表的功能与栈的功能是一样的,一开始的时候想到先扫描一遍给出的字符串s,使用列表记录最后保留的是哪些括号,最后遍历再遍历一遍字符串s将保留的字符加入到结果集中,但是提交上去超时了

② 在官方提供的思路中也是使用栈来进行解决的,思路是使用列表来做括号匹配,使用一个列表来记录需要删除的括号对应的下表的列表,假如是左括号那么进栈,遇到右括号但是记录的列表为空那么说明需要将这个右括号删除,假如栈不为空那么直接弹出左括号,最后再遍历一遍字符串s将不需要删除的字符加入到结果集中即可

③ 需要注意以下几个python常用的方法

1)union方法:union() 方法返回两个集合的并集,即包含了所有集合的元素,重复的元素只会出现一次

x = {"apple", "banana", "cherry"} y = {"google", "runoob", "apple"} z = x.union(y)

输出结果为:

{'cherry', 'runoob', 'google', 'banana', 'apple'}

2)python中的列表相当于栈了,可以弹出栈顶与栈底的元素

3)在python中 None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()都相当于False

3. 代码如下:

官方的代码:

class Solution:
    def minRemoveToMakeValid(self, s: str) -> str:
        indexes_to_remove = set()
        stack = []
        for i, c in enumerate(s):
            if c not in "()":
                continue
            if c == "(":
                stack.append(i)
            # 在python中 None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()都相当于False
            elif not stack:
                indexes_to_remove.add(i)
            else:
                stack.pop()
        print(indexes_to_remove, stack)
        indexes_to_remove = indexes_to_remove.union(set(stack))
        string_builder = []
        for i, c in enumerate(s):
            if i not in indexes_to_remove:
                string_builder.append(c)
        # 拼接字符串
        return "".join(string_builder)

我一开始的时候写的:

class Solution:
    def minRemoveToMakeValid(self, s: str) -> str:
        # 一个比较容易想到的方法是统计当前左右括号的数目
        res = ""
        # 列表就相当于一个栈
        leftstack, rightstack = [], []
        for i in range(len(s)):
            if s[i] == '(':
                leftstack.append(i)
            elif s[i] == ')':
                rightstack.append(i)
        leftindex, rightindex = len(leftstack) - 1, len(rightstack) - 1
        while leftindex >= 0 and rightindex >= 0:
            # 为了避免出现这样的情况l)(ee(e)所以在删除的时候需要加上一个限制条件就是右括号与的下表是
            # 一定大于左括号的下表的
            if leftstack[leftindex] < rightstack[rightindex]:
                # leftstack.pop()
                # rightstack.pop()
                leftindex -= 1
                rightindex -= 1
            #     需要加上这样的限制因为可能出现这样的str: "())()((("
            else:
                leftindex -= 1
                leftstack.pop()
        while len(rightstack) > len(leftstack) and len(rightstack) > 0:
            # 注意应应该是从前面开始删除
            rightstack.pop(0)
            rightindex -= 1
        while len(leftstack) > len(rightstack) and len(leftstack) > 0:
            leftstack.pop(0)
            leftindex -= 1
        for i in range(len(s)):
            if s[i] == '(' or s[i] == ')':
                if i in leftstack or i in rightstack:
                    res += s[i]
            else: res += s[i]
        return res

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章