4.1日:有效括号的嵌套深度
有效括号字符串仅由 "("
和 ")"
构成,并符合下述几个条件之一:
- 空字符串
- 连接,可以记作
AB
(A
与B
连接),其中A
和B
都是有效括号字符串 - 嵌套,可以记作
(A)
,其中A
是有效括号字符串
类似地,我们可以定义任意有效括号字符串 s
的嵌套深度depth(S)
:
s
为空时,depth("") = 0
s
为A
与B
连接时,depth(A + B) = max(depth(A), depth(B))
,其中A
和B
都是有效括号字符串s
为嵌套情况,depth("(" + A + ")") = 1 + depth(A)
,其中A
是有效括号字符串
例如:""
,"()()"
,和 "()(()())"
都是有效括号字符串,嵌套深度分别为 0,1,2,而 ")("
和 "(()"
都不是有效括号字符串。
给你一个有效括号字符串 seq
,将其分成两个不相交的子序列A
和 B
,且 A
和 B
满足有效括号字符串的定义(注意:A.length + B.length = seq.length)
。
现在,你需要从中选出 任意 一组有效括号字符串 A
和B
,使 max(depth(A), depth(B))
的可能取值最小。
返回长度为 seq.length
答案数组 answer
,选择A
还是B
的编码规则是:如果 seq[i]
是A
的一部分,那么 answer[i] = 0
。否则,answer[i] = 1
。即便有多个满足要求的答案存在,你也只需返回 一个。
示例:
-
输入:seq = “(()())” 输出:[0,1,1,1,1,0]
-
输入:seq = “()(())()” 输出:[0,0,0,1,1,0,1,1]
1、先复习一下有效括号的概念
class Solution(object):def isValid(self, s):""":type s: str:rtype: bool"""while '{}' in s or '[]' in s or '()' in s:s = s.replace('{}','')s = s.replace('[]','')s = s.replace('()','')return s == ''
2、回过来看这道题
分析:
要求划分出使得最大嵌套深度最小的分组,首先需要知道如何计算嵌套深度。可以通过栈实现括号匹配来计算,维护一个栈
s
,从左至右遍历括号字符串中每一个字符:
- 如果当前字符是
(
,就把(
压入栈中,此时这个(
的嵌套深度为栈的高度- 如果当前字符是
)
,此时这个)
的嵌套深度为栈的高度,随后再从栈中弹出一个(
下面给出括号序列(()(())())
在每一个字符处的嵌套深度:
括号序列 ( ( ) ( ( ) ) ( ) )
下标编号 0 1 2 3 4 5 6 7 8 9
嵌套深度 1 2 2 2 3 3 2 2 2 1
知道如何计算嵌套深度,问题就简单了:只要在遍历过程中,保证栈内一半的括号属于序列A
,一半的括号属于序列B
,就能保证拆分后最大的嵌套深度最小,是当前最大嵌套深度的一半。要实现这样的对半分配,只需要把奇数层的(
分配给A
,偶数层的(
分配给B
即可。对于上述的例子,可以将嵌套深度为1
和3
的所有括号(())
分配给A
,嵌套深度为2
的所有括号()()()
分配给B
。
class Solution:def maxDepthAfterSplit(self,seq):ans = []d = 0for c in seq:if c == '(':d += 1ans.append(d % 2)if c == ')':ans.append(d % 2)d -= 1return ans
时间复杂度:O(n),n为字符串的长度,只需要遍历一次括号字符串即可。
空间复杂度:O(1)