题目
给出一个字符串 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)