题目:
1、空串是一个合法括号匹配序列,且深度为0
2、如果x和y是合法序列,则xy也是合法序列,且深度为max(x,y)
3、如果x是合法序列,则(x)也是合法序列,、且深度比x加1
例如:()()()的深度为1,(())的深度为2,(())()的深度为2。
题目给出一个括号序列,然后输出最大匹配深度。
思路一:
首先,设置个值max,从头遍历,遇到"(“就max加1。设置一个布尔值,初始为true,当遇到”)",时,设为false,这个布尔变量的作用,是用来标记,一个旧的重叠的括号序列是否结束,用来判断后面再遇到"("时,是应该max继续加1,还是一个新的重叠括号的开始。如果为false,是新的开始,则需要把前面的max值记录下来,保存在list中,然后重置max为1,继续上述过程。
最后,对list排序,最大值即为最大深度。
代码:
public static void main(String[] args) {
String str="(((())))(())((((()))))";
boolean is=true;
ArrayList<Integer> l=new ArrayList<>();
int max=0;
for(int i=0;i<str.length();i++) {
char c=str.charAt(i);
if(c=='('&&is) {
max++;
}else if(c==')') {
is=false;
}else if(c=='('&&!is) {
l.add(max);
max=1;
is=true;
}
}
l.add(max);
Collections.sort(l);
System.out.println(l);
System.out.println(l.get(l.size()-1));
}
第二种解法
我们可以假设每一个括号为终止括号来遍历所有,找出最长的结果。
申请一个数组来保存每一位为终止括号时的最长结果。
如果当前遍历到左括号,那么,他不可能是终止括号,因此,为0,如果当前是右括号,则此时看他前一位,前一位的结果表示他前面已经有多少个匹配成功的,然后,追溯arr[i-1]的前一位,如果是右括号,则返回0,如果是左括号,说明+2,然后再加上再前一位的结果。
代码
public static int f1(String str){
char[] chars=str.toCharArray();
int[] dp=new int[chars.length];
int res=0;
int pre=0;
for (int i = 1; i < chars.length; i++) {
if(chars[i]==')') {
pre=i-dp[i-1]-1;
if(pre>=0&&chars[pre]=='('){
dp[i]=dp[i-1] + 2 + (pre > 0 ? dp[pre-1]:0);
}
}
res=Math.max(res,dp[i]);
}
return res;
}