题目描述
// 32. 最长有效括号
// 给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)
// 括号子串的长度。
题解
// 栈辅助法 + 贪心
// 定义答案保存位res,排除特殊情况。
// 构建栈stack用来保存'('的位置索引(用来模拟匹配),
// 和用于计数下一子串长度的起始点位置索引。(只要用遍历索引i,减去stack中的子串
// 起始点位置索引,就能得到匹配子串的长度。)
// 初始化stack,将-1压入stack中,作为字符组的伪首元素位置,
// for循环遍历s中的元素记为s.charAt(i),如果是待匹配的左括号'(',
// 则将左括号的索引压入栈stack中,此时需要求子串长度可以通过i - stack.peek(),下同。
// 如果遍历到s的字符s.charAt(i)为右括号')',则stack中元素出栈(相当于完成一次匹配)
// 出栈之后stack如果不为空,则stack一定保存着匹配子串的起始点位置索引(即匹配子串
// 第一个左括号的前一个位置)。用当前遍历索引i减去这个起始点位置索引stack.peek(),
// 得到的结果和res作比较,大值赋给res。
// 如果stack为空,说明遍历索引i连续遇到了右括号,至少多执行了一次stack.pop(),
// 使得stack为空,那么我们就把当前的i push进stack中,更新我们的起始点位置索引stack.peek()
// 如此遍历循环,最后返回res即可。
// 执行用时:3 ms, 在所有 Java 提交中击败了44.85%的用户
// 内存消耗:38.8 MB, 在所有 Java 提交中击败了5.03%的用户
import java.util.Stack;
class Solution {
public int longestValidParentheses(String s) {
int res = 0;
if (s == null || s.length() == 0)
return res;
Stack<Integer> stack = new Stack<>();
stack.push(-1);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
}
else if (s.charAt(i) == ')') {
stack.pop();
if (stack.isEmpty()) {
stack.push(i);
}
else {
res = Math.max(res, i - stack.peek());
}
}
}
return res;
}
}