# 資訊 :::info - Question: 1249. Minimum Remove to Make Valid Parentheses - From: Leetcode Daily Challenge 2024.04.06 - Difficulty: Medium ::: --- # 目錄 :::info [TOC] ::: --- # 題目 Given a string `s` of `'('` , `')'` and lowercase English characters. Your task is to remove the minimum number of parentheses ( `'('` or `')'`, in any positions ) so that the resulting parentheses string is valid and return any valid string. Formally, a parentheses string is **valid** if and only if: * It is the empty string, contains only lowercase characters, or * It can be written as `AB` (`A` concatenated with `B`), where `A` and `B` are valid strings, or * It can be written as `(A)`, where `A` is a valid string. > Example 1: :::success * Input: `s = "lee(t(c)o)de)"` * Output: `"lee(t(c)o)de"` * Explanation: `"lee(t(co)de)"` , `"lee(t(c)ode)"` would also be accepted. ::: > Example 2: :::success * Input: `s = "a)b(c)d"` * Output: `"ab(c)d"` ::: > Example 3: :::success * Input: `s = "))(("` * Output: `""` * Explanation: An empty string is also valid. ::: > Constraints: :::success * 1 <= `s.length` <= $10^5$ * `s[i]` is either `'('` , `')'`, or lowercase English letter. ::: --- # 解法 ## 概念 有酷的題目,這題的解法一樣是拿 stack 解決,把需要移除掉的括號移掉就好,但對於佐括號和右括號的移法判斷剛好會相反,所以需要從左到右移除右括號,再由右到左移除左括號,這樣才能把全部不合法的括號移除 兩個小細節注意: 1. 由右到左移除時 for loop 的順序要注意 2. 最後解答要記得 reverse 再回傳 詳細可以看 code 的 comment,註解寫得很詳細! ## 程式碼 ```python= class Solution: def minRemoveToMakeValid(self, s: str) -> str: stack = [] ans = [] # From left to right for i in range(len(s)): if s[i] == '(': stack.append('(') ans.append('(') elif s[i] == ')': if stack and stack[-1] == '(': # if not stack -> ')' is illegal and thus remove stack = stack[:-1] ans.append(')') else: # lower case English letter ans.append(s[i]) # Transform ans from list to string s = ''.join(ans) stack = [] ans = [] # From right to left for i in range(len(s)-1,-1,-1): if s[i] == ')': stack.append(')') ans.append(')') elif s[i] == '(': if stack and stack[-1] == ')': # if not stack -> ')' is illegal and thus remove stack = stack[:-1] ans.append('(') else: # lower case English letter ans.append(s[i]) return ''.join(ans)[::-1] ``` --- # 複雜度 ## 時間複雜度 時間最主要就是 traverse 兩次字串,所以是 $O(n)$。不過說 $O(n)$,那個係數也是有點大,像我的應該至少超過 5,這也是複雜度爛成這樣的關係吧!有機會做成 inline 的會更好! ![TimeComplexity2024](https://hackmd.io/_uploads/HJ9aVvRJR.png =80%x) ## 空間複雜度 空間部分存了兩次答案的 list 和 stack,所以會是 $O(n)$ ![SpaceComplexity2024](https://hackmd.io/_uploads/SynCEDRkR.png =80%x)