目录
有效括号字符串为空 ""
、"(" + A + ")"
或 A + B
,其中 A
和 B
都是有效的括号字符串,+
代表字符串的连接。
""
,"()"
,"(())()"
和 "(()(()))"
都是有效的括号字符串。如果有效字符串 s
非空,且不存在将其拆分为 s = A + B
的方法,我们称其为原语(primitive),其中 A
和 B
都是非空有效括号字符串。
给出一个非空有效字符串 s
,考虑将其进行原语化分解,使得:s = P_1 + P_2 + ... + P_k
,其中 P_i
是有效括号字符串原语。对 s
进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s
。
示例 1:
输入:s = "(()())(())" 输出:"()()()" 解释: 输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())", 删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。
示例 2:
输入:s = "(()())(())(()(()))" 输出:"()()()()(())" 解释: 输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))", 删除每个部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"。
示例 3:
输入:s = "()()" 输出:"" 解释: 输入字符串为 "()()",原语化分解得到 "()" + "()", 删除每个部分中的最外层括号后得到 "" + "" = ""。
提示:
1 <= s.length <= 10^5
s[i]
为 '('
或 ')'
s
是一个有效括号字符串
看懂这道题目花了好长时间。
第一感是括号配对。但是配对的目的不是把所有的括号都移除(字符串本身全部由括号对构成,所有括号都移除的话,而且题目保证s是有效括号字符串,就直接返回空字符串就好了),而是找到每个原语字符串的最外层的括号对并移除。
所以问题就变成了寻找配对的括号,并判断是保留还是移除的问题。
寻找配对括号的经典做法是利用栈。碰到就入栈; 碰到时,可以肯定与之配对的一定位于栈顶(假设输入字符串是合法的),将栈顶的弹出。此时需要判断这一对括号是需要保留到在输出结果字符串中,还是直接扔掉。
对于一对处于原语字符串最外层的括号对,当它们配对出栈时,栈一定是变空了。栈从空到下一次空的过程,则是扫描了一个原语的过程。一个原语中,首字符和尾字符应该舍去,其他字符需放入结果字符串中。
因此,对于每一个新的字符,如果是 则将字符入栈后,入栈后栈的深度为 1,表明该字符为一个原语最外层括号对的左括号,则不把字符放入结果;在遇到 并将栈顶字符出栈后,如果栈为空,表明该字符为一个原语最外层括号对的右括号,也不应该放入结果。其他情况下,需要把字符放入结果。
以下代码实现中,对流程进行了部分优化,先判断是否为并进行必要的出栈处理。如果是且出栈处理后栈为空表明当前字符为为一个原语最外层括号对的右括号,不必放入结果;如果不是且栈为空表明当前字符为为一个原语最外层括号对的左括号,也不必放入结果。
- class Solution:
- def removeOuterParentheses(self, s: str) -> str:
- ans = ''
- mystack = deque()
- for c in s:
- if c==")":
- mystack.pop()
- if len(mystack)>0:
- ans = ans + c
- if c=="(":
- mystack.append(c)
- return ans
执行用时:44 ms, 在所有 Python3 提交中击败了56.36%的用户
内存消耗:15.1 MB, 在所有 Python3 提交中击败了30.06%的用户
回到总目录:Leetcode每日一题总目录(动态更新。。。)