1190 反转每对括号间的子串【python3】

题目

给出一个字符串 s(仅含有小写英文字母和括号)。
请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。
注意,您的结果中 不应 包含任何括号。
例如:

输入:s = "(u(love)i)"
输出:"iloveu"
解释:先反转子字符串 "love" ,然后反转整个字符串。

代码&思路

暴力 40ms

初步的设想是找出每一对括号的坐标记录下来,之后对于每一对括号内的子串进行翻转。
如果是先找出(,再找出最近的)的可行性较低,因为对于括号嵌套的情况是比较麻烦的。实际上是要找到最后一个(和它最近的)即配对,然后再找到倒数第二个(以及和它最近的、之前没有配对过的)组成一对。
因此反向思考,先找出第一个)再反向遍历这个右括号前面的部分,找到离它最近的还没有配对过的)。判断左括号是否配对过,我们可以用一个数组记录配对状态。这个方法比先找出(更快一些。

class Solution:
    def reverseParentheses(self, s: str) -> str:
        L=[] # 记录左括号的坐标
        R=[] # 记录相应的右括号位置
        S0=[x for x in s]
        flag=[0]*len(s)
        
        # 记录一对括号的位置:遍历到右括号的时候找到最近的,没有被‘使用’过的左括号
        for i in range(len(s)):
            if s[i]==')':
                R.append(i)
                for j in reversed(range(i)):
                    if flag[j]==0 and s[j]=='(':
                        L.append(j)
                        flag[j]=1
                        break
        #print(R)
        #print(L)
        # 反转每对括号内的子串
        for i in range(len(L)):
            tmp=S0[L[i]+1:R[i]]
            tmp.reverse()
            S0[L[i]+1:R[i]]=tmp 

        ans=''
        for x in S0:
            if x not in '()':
                ans=ans+x
        return ans

栈运用 40ms

有了暴力破解的思路,发现这一题其实可以运用栈来完成,更加简洁。
遍历整个字符串,遍历到除了)以外的字符时,直接入栈。当遍历到)时,出栈,直到把第一个、也就是离它最近的(也给出栈。这个时候已出栈的子串已经是反转后的结果了,左右括号不再入栈,那么就可以保证每次反转的都是一对括号内的子串了。
比较与暴力解的做法,相当于在配对括号的同时就把子串也反转了。
最后运行时间相同,但是内存少了0.1MB

class Solution:
    def reverseParentheses(self, s: str) -> str:
        stack=[] # 栈
        
        for x in s:
            # 不是),入栈
            if x!=')':
                stack.append(x)
            # 遍历到),出栈直到遇见(
            else:
                tmp=[] # 中间栈
                for y in reversed(stack):
                    if y!='(':
                        tmp.append(stack.pop())
                    else: # 遇到(,出栈,出栈后的子串已经是反转的结果,左右括号不再入栈
                        stack.pop()
                        for z in tmp:
                            stack.append(z)
                        break


        return ''.join(stack)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值