这里是题目描述:LeetCode-1111.有效括号的嵌套深度
这道题的题意确实有点难理解,大家可能要仔细的理解一下。简单的说,就是将给定的有效括号串分成A、B两个子序列;A、B也必须是合法的有效括号串;组成A、B的各个字符seq[i]可以不连续;分好的A、B应该满足max(A嵌套深度,B嵌套深度)最小。分配给A的字符用0表示,分配给B的字符用1表示。
示例1:
输入:seq="(()())"
输出:[0,1,1,1,1,0]
解释:A="()" B="()()" max(depth(A),depth(B))=1
示例2:
输入:seq="()(())()"
输出:[0,0,0,1,1,0,1,1]
解释:A="()()" B="()()" max(depth(A),depth(B))=1
又因为题目中说明答案不唯一,因此也可以是:
输出:[0,0,0,1,1,0,0,0]
解释:A="()()()" B="()" max(depth(A),depth(B))=1
解题方法:根据括号层级奇偶性分配
我们的分配准则应该是:尽量减小嵌套深度,同时应该将嵌套深度在A、B上平均分配。因此。我们开辟一长度个为seq.length的数组degree记录seq上每个括号符号的嵌套层级深度,当前深度初始化为0;遍历seq,当遍历到左括号,当前深度+1并赋值给degree[i];当遍历到右括号,当前深度赋值给degree[i]并-1;最后将所有degree为奇数的括号分给A、degree为偶数的赋值给B
示例1:
seq="()(())()"
degree=[1,1,1,2,2,1,1,1]
answer=[0,0,0,1,1,0,0,0]
A="()()()" B="()" max(depth(A),depth(B))=1
示例2:
seq="(()(())())"
degree=[1,2,2,2,3,3,2,2,2,1]
answer=[0,1,1,1,0,0,1,1,1,0]
A="(())" B="()()()" max(depth(A),depth(B))=2
题解代码:
class Solution {
public int[] maxDepthAfterSplit(String seq) {
if(seq.length()==0)
{
return new int[seq.length()];
}
int[] degree=new int[seq.length()]; //记录seq中每个字符的嵌套层级
int curDegree=0;
for(int i=0;i<seq.length();i++)
{
char ch=seq.charAt(i);
if(ch=='(')
{
curDegree+=1;
degree[i]=curDegree;
}
else //ch==')'
{
degree[i]=curDegree;
curDegree-=1;
}
}
for(int i=0;i<degree.length;i++) //奇数层级分配给子序列0,偶数层级分配给子序列1
{
degree[i]=(degree[i]+1)%2;
}
return degree;
}
}
时间复杂度:O(n)
空间复杂度:O(n)
当然,我们也可以不需要记录每个括号嵌套深度的数组,只需要一个记录当前嵌套深度的变量,初始为0,根据遍历到的左右括号+1或-1,并根据变量当前的奇偶性将当前括号分给A或B就行