【20190911】【每天一道算法题】删除最外层的括号(栈)

问题

有效括号字符串为空 ("")、"(" + 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 是一个有效括号字符串


思路及代码

# 方法一:栈
# 时间复杂度:O(n)
class Solution:
    def removeOuterParentheses(self, S: str) -> str:
        result = ''
        stack = []
        start = 0
        for i in range(len(S)):
            if S[i] == '(':   # 因为这里有效括号是(),)(这并不是有效括号,所以只要遇到(就进栈,)就出栈是正确的!
                stack.append(S[i])
            else:
                stack.pop()
            if stack == []:
                result += S[start+1:i]   # 这一步就相当于删掉了最外层的括号(利用了字符串切片)
                start = i+1
        return result
		
		
# 方法二:计数法。只要( 和 )的数量相同,那么就表明找到一个原语分解。
# 时间复杂度:O(n)
class Solution:
    def removeOuterParentheses(self, S: str) -> str:
        num1, num2 = 0, 0
        start = num1 + num2
        result =''
        for i in range(len(S)):
            if S[i] == '(':
                num1 += 1
            else:
                num2 += 1
            if num1 == num2:
                result += S[start+1:num1+num2-1]   # 注意这里的字符串切片空间(保证去掉最外面括号)
                start = num1 + num2
        return result
		
		
# 方法三:双指针法。遇到( cnt加一;遇到 )cnt减一,如果cnt==0,那么利用start,end指针对字符串进行切片。
# 时间复杂度:O(n)
class Solution:
    def removeOuterParentheses(self, S: str) -> str:
        cnt, start, end = 0, 0, 0
        result =''
        for i in range(len(S)):
            cnt +=1 if S[i] == '(' else -1
            if cnt == 0:
                end = i
                result += S[start+1: end]
                start = end+1
        return result

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Satisfying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值