/**
* 括号有效问题
*/
public class Parentheses {

/**
* 判断一个括号字符串是否有效
*
* @param s 字符串
* @return 是否有效
*/
public static boolean valid(String s) {
char[] chars = s.toCharArray();
int count = 0;
for (char c : chars) {
count += c == '(' ? 1 : -1;
if (count < 0) {
return false;
}
}
return count == 0;
}

/**
* 使给定的括号字符串有效,需要添加几个字符
*
* @param s 字符串
* @return 需要添加的长度
*/
public static int needParentheses(String s) {
char[] chars = s.toCharArray();
int count = 0;
int need = 0;
for (char c : chars) {
if (c == '(') {
count++;
} else {
if (count == 0) {
need++;
} else {
count--;
}
}
}
return need + count;
}

/**
* 给定一个括号字符串,返回最大嵌套几层
*
* @param s 字符串
* @return 层数
*/
public static int maxDeep(String s) {
if (!valid(s)) {
return 0;
}
char[] chars = s.toCharArray();
int count = 0;
int max = 0;
for (char c : chars) {
count += c == '(' ? 1 : -1;
max = Math.max(count, max);
}
return max;
}

/**
* 给定一个括号字符串,返回最长的有效子串
*
* @param s 字符串
* @return 最长的有效子串的长度
*/
public static int maxValidLength(String s) {
char[] chars = s.toCharArray();
int max = 0;
int pre;
// 以i结尾,有效括号字符串的长度
int[] dp = new int[chars.length];
for (int i = 1; i < chars.length; i++) {
// '('结尾必定无效
if (chars[i] == '(') {
continue;
}
// 找到当前位置 以前面已经有效的子串为轴的 对称位置
pre = i - dp[i - 1] - 1;
// 位置必须不小于0并且是'('
if (pre >= 0 && chars[pre] == '(') {
// 当匹配之后,长度比前一位至少大2,还要加上 pre-1 位置的有效长度
dp[i] = dp[i - 1] + 2 + (pre - 1 >= 0 ? dp[pre - 1] : 0);
}
max = Math.max(max, dp[i]);
}
return max;
}

}