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.
解题思想
顺序扫描字符串:
初始化:在栈中压入-1
一、若碰到‘(’,则把当前位置压入栈中
二、若碰到‘)’:
(1)、如果栈顶元素不是‘(’,则把当前位置压入栈中;
(2)、如果栈顶元素时‘(’:栈顶元素出栈,当前的合法子串长度 = 当前字符索引 - 新的栈顶元素;更新最大子串长度
例如以下字符串
扫描到第0个字符‘(’时,0入栈
扫描到第1个字符‘)’时,栈顶对应字符为‘(’,把栈顶0出栈,当前合法子串长度 = 1 - 新的栈顶元素(-1) = 2;
扫描到第2个字符‘)’时,栈顶为-1,因此2入栈
扫描到第3个字符‘(’时,3入栈
扫描到第4个字符‘)’时,栈顶对应字符为‘(’,把栈顶3出栈,当前合法子串长度 = 4 - 新的栈顶元素(2) = 2;
扫描到第5个字符‘(’时,5入栈
扫描到第6个字符‘)’时,栈顶对应字符为‘(’,把栈顶5出栈,当前合法子串长度 = 6 - 新的栈顶元素(2) = 4;
需要注意的是:当前合法子串当长度 != 当前索引 - 与当前的‘)’匹配的‘(’的索引 + 1, 例如扫描到第6个字符‘)’时,当前合法子串长度不是等于6-5+1 = 2,还要考虑到它前面已经匹配的3、4号位
算法时间空间复杂度都是O(n)
public int longestValidParentheses(String s) {
if(s == null) {
return 0;
}
Stack<Integer> stack = new Stack<Integer>();
stack.push(-1);
int result = 0;
for(int i=0; i<s.length(); i++) {
if(s.charAt(i)=='(') {
stack.push(i);
} else { //)
int topIndex = stack.peek();
if(topIndex>=0 && s.charAt(topIndex)=='(') {
stack.pop();
if(result < (i-stack.peek())) {
result = i-stack.peek();
}
} else {
stack.push(i);
}
}
}
return result;
}