题目描述:
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
解题思路:
首先定义一个栈,但栈中存储的元素不在是括号,而是存储的是遍历数组中的下标。
- 初始化栈,则先加入-1到栈中,因为考虑到数组下标是从0开始的
- 当我们遍历到“(”,则直接入栈
- 当遍历到“)”,我们则要弹出栈顶元素,表示配对成功。这里还要判断
- 栈不为空,
- 栈为空,则表示我们遍历到此时,“)”个数已经大于“(”的个数,所以我们将当前的下标压入栈中,表示从该处重新开始连续性
- 比较最大值跟(遍历的下标与栈顶元素的差值)作为最终的最大值
图解:
以“(())(()”为例
初始状态
/**
* 最长的有效括号
* 题目:
* 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
* <p>
* 示例 1:
* <p>
* 输入: "(()"
* 输出: 2
* 解释: 最长有效括号子串为 "()"
* 示例 2:
* <p>
* 输入: ")()())"
* 输出: 4
* 解释: 最长有效括号子串为 "()()"
*
* @author pengjie_yao
* @date 2020/1/9 10:12
*/
public class LongValidParenteses {
/**
* 栈顶每次保存的都是上一个“(”的位置即可,我们只要取知之间的最大值作为总数
* @return
*/
public static int longestValidParentheses (String s) {
Stack<Integer> stack = new Stack<Integer>();
char[] chars = s.toCharArray();
stack.push(-1);
int max = 0;
for (int i = 0; i < chars.length; i++) {
// 如果是“(” 直接入栈
if (chars[i] == '(') {
// 将该所在数组入栈,栈中存的是该元素的小标
stack.push(i);
}else {
// 遍历到的是')',则弹出栈顶元素
stack.pop();
// 这里要看一个如果栈为空,则要把当前数组下标的元素放入栈中。这里主要是为了连续性
// 栈为空的情况:表示遍历到的)大于入栈的(,所以要记录重新连续的位置
if (stack.isEmpty()) {
stack.push(i);
}else {
// 取遍历到的下标与栈顶元素的差值与当前的最大值进行比较
max = Math.max(max, i - stack.peek());
}
}
}
return max;
}
public static void main(String[] args) {
System.out.println(longestValidParentheses("()"));
}
}