[LeetCode] 32. Longest Valid Parentheses
Given a string containing just the characters '('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: s = "(()" Output: 2 Explanation: The longest valid parentheses substring is "()".
Example 2:
Input: s = ")()())" Output: 4 Explanation: The longest valid parentheses substring is "()()".
Example 3:
Input: s = "" Output: 0
Constraints:
0 <= s.length <= 3 * 104
s[i]
is'('
, or')'
.
最长有效括号。
给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
这个题可以用动态规划做,但是不是很容易理解,我这里给出一个栈的解法。首先创建一个 stack,然后放入一个值 -1,这个 -1 的意思是记录最后一个无效的 index。接着开始遍历每个字符
- 遇到左括号,无条件放入 stack
- 遇到右括号,不需要将右括号入栈,但是需要做一些判断
- 判断此时栈是否为空,如果为空,说明之前合法的括号对都处理完毕了,则将当前的 index = i 入栈,说明之后的有效括号对(如果还有的话)的 start index 是从 i 开始的
- 如果不为空,则将栈顶元素 pop 出来(应该会是个左括号)
- 如果 pop 之后 stack 为空,则将当前 index = i 入栈,如果将来后面剩余的部分还有合法子串,这个位置就是起点
- 如果 pop 之后 stack 不为空,还是结算一下此时的最大长度,是 res 和 i - stack.peek() 之间的较大者
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int longestValidParentheses(String s) { 3 // corner case 4 if (s == null || s.length() == 0) { 5 return 0; 6 } 7 8 // normal case 9 Stack<Integer> stack = new Stack<>(); 10 int res = 0; 11 int start = -1; 12 for (int i = 0; i < s.length(); i++) { 13 if (s.charAt(i) == '(') { 14 stack.push(i); 15 } else { 16 if (stack.isEmpty()) { 17 start = i; 18 } else { 19 stack.pop(); 20 if (stack.isEmpty()) { 21 res = Math.max(res, i - start); 22 } else { 23 res = Math.max(res, i - stack.peek()); 24 } 25 } 26 } 27 } 28 return res; 29 } 30 }
JavaScript实现
1 /** 2 * @param {string} s 3 * @return {number} 4 */ 5 var longestValidParentheses = function(s) { 6 // corner case 7 if (s === null || s.length === 0) { 8 return 0; 9 } 10 11 // normal case 12 let start = -1; 13 let res = 0; 14 let stack = []; 15 for (let i = 0; i < s.length; i++) { 16 if (s.charAt(i) == '(') { 17 stack.push(i); 18 } else { 19 if (stack.length === 0) { 20 start = i; 21 } else { 22 stack.pop(); 23 if (stack.length === 0) { 24 res = Math.max(res, i - start); 25 } else { 26 res = Math.max(res, i - stack[stack.length - 1]); 27 } 28 } 29 } 30 } 31 return res; 32 };