给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
题目
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s = ""
输出:0
提示:
0 <= s.length <= 3 \* 104
s\[i] 为 '(' 或 ')'
思路
通常涉及括号匹配问题的题目都可以考虑使用栈来解决。这道题也不例外。我们创建一个栈,然后遍历字符串中的每个字符。
如果当前字符是左括号 (,那么就将其推入栈中。
如果当前字符是右括号 ),那么我们需要检查栈是否为空。若栈为空,则说明当前的右括号没有合适的左括号与之匹配,直接忽略即可;否则弹出栈顶元素,并计算当前有效匹配的字符串长度。
特别地,对于这道题,我们还需要注意一种情况:即当我们遍历到当前位置时,栈中仍有剩余元素,但已经无法进行匹配时,我们需要将栈中所有元素弹出,并更新最长有效匹配长度。
下面给出基于以上思路的Javascript代码实现,注意每个操作需要检查栈是否为空。
/**
* @param {string} s
* @return {number}
*/
var longestValidParentheses = function(s) {
let stack = [-1];
let maxLen = 0;
for (let i = 0; i < s.length; i++) {
if (s.charAt(i) === '(') {
stack.push(i); // 将左括号入栈
} else {
stack.pop(); // 弹出栈顶元素
if (stack.length === 0) {
stack.push(i); // 若栈为空,则将当前右括号入栈(作为下一个合法括号序列的起点)
} else {
maxLen = Math.max(maxLen, i - stack[stack.length - 1]); // 栈非空则更新最大长度
}
}
}
return maxLen;
};
- 时间复杂度:,算法中通过遍历字符串一次来处理所有括号,因此时间复杂度为 ,其中 是给定字符串的长度。
- 空间复杂度:,空间复杂度取决于使用的栈的大小。在最坏情况下,如果给定的字符串中每个字符都是左括号
(,那么栈将增长到 ,因此空间复杂度为 。