这题看起来简单但是容易漏很多test case。
错误的思路
一开始我的思路是: 遇到左括号就入栈、计数;遇到右括号先检查栈是否为空;不为空就出栈、计数,为空就结束本次计数
上面这种思路有漏洞,比如当(()的情况时,返回的结果将会是3
正确的方式
遇到左括号就把它的index压栈,遇到右括号先检查栈是否为空,为空就说明是())这种情形,所以把start右移一位,直到找到一个(为止;
不为空就pop出一个元素,这时候要进行第二次判空,如果为空,说明是()了,判断i-start+1;如果不为空就说明是((),那么返回i-peak+1
另外说一下,这道题Leetcode一直TLE,我以为代码有问题,比对了半天,结果贴网上的代码上去,同样TLE..醉了,leetcode的一个很长的((((((...的test case过不了(有时候能过),不知道是不是网络的问题。
public int longestValidParentheses(String s) {
if (s == null || s.length() == 0)
return 0;
LinkedList<Integer> stack = new LinkedList<Integer>();
int start = 0;
int max = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else {
if (stack.isEmpty()) {
//还没pop就empty了,说明遇到())了
start = i + 1;
} else {
stack.pop();
//注意 i-stack.peak()不用加1了
max = stack.isEmpty() ? Math.max(max, i - start + 1) : Math.max(max, i - stack.peek());
}
}
}
return max;
}
programcreek上一个更简洁的做法:
跟上面不同的是,先压了一个-1进stack,第二,右括号匹配之后也把当前index压进去,peek就成了类似上面的start-1。
public class Solution {
public int longestValidParentheses(String s) {
int maxans = 0;
Stack<Integer> stack = new Stack<>();
stack.push(-1);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else {
stack.pop();
if (stack.empty()) {
stack.push(i);
} else {
maxans = Math.max(maxans, i - stack.peek());
}
}
}
return maxans;
}
}