版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/89103739
有效括号字符串为空 ("")
、"(" + 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:
输入:"(()())(())"
输出:"()()()"
解释:
输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())",
删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。
示例 2:
输入:"(()())(())(()(()))"
输出:"()()()()(())"
解释:
输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))",
删除每隔部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"。
示例 3:
输入:"()()"
输出:""
解释:
输入字符串为 "()()",原语化分解得到 "()" + "()",
删除每个部分中的最外层括号后得到 "" + "" = ""。
提示:
S.length <= 10000
S[i]
为"("
或")"
S
是一个有效括号字符串
解题思路
这个问题首先想到的解法是通过栈。对于例1
,我们遍历S
( ( ) ( ) ) ( ( ) )
↑
假设我们遍历到的元素是c
,如果c!=')'
,我们将c
压入栈中
( ( ) ( ) ) ( ( ) )
↑
s: (
接着我们发现遍历到的元素c
依旧不是)
,我们依旧将c
压入栈中,并且此时我们发现栈的长度大于1
,说明栈中有大于一个(
,那么我们需要将此时的c
添加到结果中。
( ( ) ( ) ) ( ( ) )
↑
s: ((
res: (
当我们继续遍历的时候,我们发现遍历到的c
是)
,我们判断出此时栈的长度大于1
,说明栈中有大于一个(
。我们将c
添加到res
中,并且我们知道此时的c
和栈顶必然匹配成功,所以我们需要将栈顶元素弹出。
( ( ) ( ) ) ( ( ) )
↑
s: (
res: ()
依照这种思路继续下去即可。
class Solution:
def removeOuterParentheses(self, S: str) -> str:
s, res = list(), ""
for c in S:
if c == ')':
if len(s) > 1:
res += c
s.pop()
else:
s.append(c)
if len(s) > 1:
res += c
return res
借助于摩尔投票算法的思想,我们可以不用栈,而是通过变量记录栈的长度。当c=='('
长度大于0
的时候,我们需要将c
加入到结果中,当c==')'
并且栈的长度大于1
的时候,我们需要将c
加入到结果中。
class Solution:
def removeOuterParentheses(self, S: str) -> str:
res, opened = "", 0
for c in S:
if c == '(' and opened > 0:
res += c
if c == ')' and opened > 1:
res += c
opened += 1 if c == '(' else -1
return res
算法的思路和上面是一致的。
reference:
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!