题目
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
For “(()”, the longest valid parentheses substring is “()”, which has length = 2.
Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.
分析
典型的括号题,思路如下
用栈,也是下面的解法。
每次来了‘(’之后,无条件压栈。如果碰到’)’的话,如果栈不为空,就消除栈内剩余的’(’
第一:消除掉’(‘之后,如果栈内还有剩余的‘(’的话,最长的合法长度就是:maxLength = Math.max(i - (int)stack.peek() , maxLength); 也就是取:当前’)’的index减去栈顶元素的index 和 原来max_length 两者的最大值。
例如:对于这种情况:()(()(),可以正确的得出最大值为4。
第二:消除掉’)’之后,栈内没有剩余的‘(’了。此时需要引入一个新的变量start,用于表示合法括号字符串的起点。
例如:对于这种情况:())()(),可以正确的得出最大值为4。
start初始为-1,之后每次碰到‘)’且栈为空的时候更新为当前‘)’的index。也就是说无法消除的)之后的括号不可能再和前面的括号合并在一起计算最长序列,所以更新start。
思想很像 http://blog.csdn.net/sinat_16014143/article/details/78321683
动态规划法
将大问题化为小问题,我们不一定要一下子计算出整个字符串中最长括号对,我们可以先从后向前,一点一点计算。假设d[i]是从下标i开始到字符串结尾最长括号对长度,s[i]是字符串下标为i的括号。如果s[i-1]是左括号,如果i + d[i] + 1是右括号的话,那d[i-1] = d[i] + 1。如果不是则为0。如果s[i-1]是右括号,因为不可能有右括号开头的括号对,所以d[i-1] = 0。
复杂但是很好理解的方法
要提高时间复杂度。比如((()()),先遍历一遍将所有的()替换成00,得到((0000),再遍历一遍,替换所有的(00…00)这种形式字符串为000…000,这里我们得到(000000,直到遍历完无法替换更多括号为之。如果所有符号都是0,说明是有效的。这样的时间复杂度是O(N)。
感谢 https://segmentfault.com/a/1190000003481194
和http://blog.csdn.net/worldwindjp/article/details/39460161两位博主
class Solution {
public static int longestValidParentheses(String s) {
if (s == null || s.length() == 0) {
return 0;
}
//start的下一位是字符串的开始
int start = -1;
int maxLength = 0;
Stack stack = new Stack();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else {
if (!stack.empty()) {
stack.pop();
if (stack.empty() == true) {
maxLength = Math.max(i - start, maxLength);
} else {
maxLength = Math.max(i - (int) stack.peek(), maxLength);
}
} else {
start = i;
}
}
}
return maxLength;
}
}