1 题目链接
2 题目大意
给你一个 「有效括号字符串」 seq,请你将其分成两个不相交的有效括号字符串,A 和 B,并使这两个字符串的深度最小。
- 不相交:每个 seq[i] 只能分给 A 和 B 二者中的一个,不能既属于 A 也属于 B 。
- A 或 B 中的元素在原字符串中可以不连续。
- A.length + B.length = seq.length
- max(depth(A), depth(B)) 的可能取值最小。
划分方案用一个长度为 seq.length 的答案数组 answer 表示,编码规则如下:
- answer[i] = 0,seq[i] 分给 A 。
- answer[i] = 1,seq[i] 分给 B 。
如果存在多个满足要求的答案,只需返回其中任意 一个 即可。
注:
- 有效括号字符串:学过栈的应该都知道括号匹配这个题,这里的有效括号字符串就是指只包含 ‘(’ 和 ‘)’ 且满足括号匹配的字符串,除此之外,空字符串也为有效括号字符串。
- 字符串的深度:举个例子,比如字符串 “(())” ,在做括号匹配的时候,栈里左括号最多的时候是两个左括号,所以它的深度就是2。
- A和B:题目的意思就是说,从seq中取出一个不连续子序列,恰好组成一个有效括号字符串,也就是A,而剩下的不连续子序列就是B,其也是个有效括号字符串,然后这种划分AB的可能性有很多种,我们取max(depth(A), depth(B)) 的取值最小的,然后取值最小的划分情况也有很多种,随便给出一种答案即可。
3 样例输入
seq = “(()())”
4 样例输出
[0,1,1,1,1,0]
注:
- A:()
- B:()()
- 上述划分情况A的深度为1,B的深度也为1,max(depth(A), depth(B))取值最小
5 思路
因为深度是在栈中左括号的最大个数,且max(depth(A), depth(B))取值要最小,那么我们只需要将左括号平均分配给A和B即可,使用两个栈分别来存A和B中的左括号,遍历seq,遇到左括号,比较当前栈A和栈B中的左括号数量,若栈A中多,则将左括号分配给B,否则分配给A,遇到右括号,随便哪个栈中只要有左括号,都可弹出,弹出的同时,将配对的括号做好标记,也就是属于A还是属于B。
6 代码
class Solution {
public int[] maxDepthAfterSplit(String seq) {
int[] ans = new int[seq.length()];
Stack<Integer> sta=new Stack<Integer>();
Stack<Integer> stb=new Stack<Integer>();
int staLength=0,stbLength=0;
for(int i=0;i<seq.length();i++){
if(seq.substring(i,i+1).equals("(")){
if(staLength<=stbLength){
sta.push(i);
staLength++;
}
else{
stb.push(i);
stbLength++;
}
}
else{
if(staLength>0){
int index = sta.pop();
ans[index]=0;
ans[i]=0;
staLength--;
}
else if(stbLength>0){
int index = stb.pop();
ans[index]=1;
ans[i]=1;
stbLength--;
}
}
}
return ans;
}
}