题目描述
有效括号字符串 仅由 “(” 和 “)” 构成,并符合下述几个条件之一:
空字符串:s 为空时,depth("") = 0。
连接,可以记作 AB(A 与 B 连接),其中 A 和 B 都是有效括号字符串:s 为 A 与 B 连接时,depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是有效括号字符串。
嵌套,可以记作 (A),其中 A 是有效括号字符串:s 为嵌套情况,depth("(" + A + “)”) = 1 + depth(A),其中 A 是有效括号字符串。
类似地,我们可以定义任意有效括号字符串 s 的 嵌套深度 depth(S):
例如:"","()()",和 “()(()())” 都是有效括号字符串,嵌套深度分别为 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。即便有多个满足要求的答案存在,你也只需返回 一个。
示例 1:
输入:seq = “(()())”
输出:[0,1,1,1,1,0]
示例 2:
输入:seq = “()(())()”
输出:[0,0,0,1,1,0,1,1]
提示:
1 <= text.size <= 10000
我的思路:一开始我以为是数据结构的那种括号匹配,直接判断’(‘所在的深度,然而,我错了。
它的意思是将这个seq有效地分配到A和B中,A中的元素全部为‘0’,B中的元素全部为’1’。
怎么分的有效呢?为了保证深度最小,这个有点类似榴莲千层蛋糕一样,你吃一层(A,奇数层),我吃一层(B,偶数层),咱俩只能你比我吃得多一层(少一层),也就是说,如果’('所在的深度为奇数,那么就是A里面的元素,反之,为B里面的元素。
代码:
class Solution {
public int[] maxDepthAfterSplit(String seq) {
char[] seq2=seq.toCharArray();
int[] deep=new int[seq.length()];
int count=0;
for(int i=0;i<seq.length();i++)
{
if(seq2[i]=='(')
{
deep[i]=(++count)%2;
}
else
{
deep[i]=(count--)%2;
}
}
return deep;
}
}
小结:
结果测出来以后,顿时觉得有点庆幸,庆幸这个题的给出的是"有效字符串seq"而不是给出一个还需要判断是否"有效"的字符串(包含{},[],(),这六种符号),那么怎么使用括号匹配的算法来判断有效呢?
括号匹配算法:
public class _1111 {
public static void main(String[] args)
{
//括号匹配问题
Scanner scanner = new Scanner(System.in);
String seq = scanner.next();
if(!Check_Length(seq))
{
System.out.println("输入字符串长度有误!");
}
else
{
if(Check_bracket(seq))
{
System.out.println("字符匹配!");
}
else
{
System.out.println("字符不匹配!");
}
}
}
private static boolean Check_Length(String seq) {
return seq.length()%2==0?true:false;
}
private static boolean Check_bracket(String seq) {
List<Integer> list_bracket=new ArrayList<Integer>();
//首先我们针对()[]{},给他们起个别名
//(=1
//)=2
//[=4
//]=5
//{=7
//}=8
//为什么要这样起名呢?
//因为为了在装入list_bracket集合之后,进行匹配消除:也就是,如果list_bracket.get(i+1)-list_bracket.get(i)==1时,我们就说它俩匹配,
// 届时list_bracket就可以使用remove()消除它俩
//那么现在你可能会有些疑问,为什么在起别名的时候:让 (=1,)=2,而不是让 (=1,)=1,呢?
//这是因为我考虑到了这样的情况:(([[{{,显然这个字符串是不匹配的,所以需要对 ( 和 ) 取不同的名字且有联系
for(int i=0;i<seq.length();i++)
{
if(seq.charAt(i)=='(')
{
list_bracket.add(1);
}
if(seq.charAt(i)==')')
{
list_bracket.add(2);
}
if(seq.charAt(i)=='[')
{
list_bracket.add(4);
}
if(seq.charAt(i)==']')
{
list_bracket.add(5);
}
if(seq.charAt(i)=='{')
{
list_bracket.add(7);
}
if(seq.charAt(i)=='}')
{
list_bracket.add(8);
}
}
boolean flag=true;
while(list_bracket.size()>0&&flag)
{
for (int i=0;i<list_bracket.size()-1;i++)
{
if(list_bracket.get(i+1)-list_bracket.get(i)==1)
{
list_bracket.remove(i);
list_bracket.remove(i);//注意:这个时候不是list_bracket.remove(i+1);,因为list_bracket的size已经改变了
flag=true;
break;
}
else
{
flag=false;
}
}
}
//剩余的没有消除的括号
if(list_bracket.size()==0)
{
return true;
}
else
{
return false;
}
}
}
结果: