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

 

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