Leetcode 1021:删除最外层的括号(超详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/89103739

有效括号字符串为空 ("")"(" + A + ")"A + B,其中 AB 都是有效的括号字符串,+ 代表字符串的连接。例如,"""()""(())()""(()(()))" 都是有效的括号字符串。

如果有效字符串 S 非空,且不存在将其拆分为 S = A+B 的方法,我们称其为原语(primitive),其中 AB 都是非空有效括号字符串。

给出一个非空有效字符串 S,考虑将其进行原语化分解,使得:S = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。

S 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 S

示例 1:

输入:"(()())(())"
输出:"()()()"
解释:
输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())",
删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。

示例 2:

输入:"(()())(())(()(()))"
输出:"()()()()(())"
解释:
输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))",
删除每隔部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"。

示例 3:

输入:"()()"
输出:""
解释:
输入字符串为 "()()",原语化分解得到 "()" + "()",
删除每个部分中的最外层括号后得到 "" + "" = ""。

提示:

  1. S.length <= 10000
  2. S[i]"("")"
  3. 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:

https://leetcode.com/problems/remove-outermost-parentheses/discuss/270022/JavaC%2B%2BPython-Count-Opened-Parenthesis

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/89103739