“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
一、题目描述
给你一个只包含 '('
和 ')
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s = ""
输出:0
提示:
0 <= s.length <= 3 * 104
s[i]
为'('
或')'
二、思路分析
题目要求我们找出最长有效(格式正确且连续)括号子串的长度,有三个限制条件:①括号组合;②返回的是长度;③长度要最长。
对于这种括号问题,我第一想法就是用栈解决。
力扣有一道题是 有效的括号 ,即判断给定的只包含 (
和 )
的字符串是否能够闭合,思路是遍历字符串元素的时候,遇到 (
就压入栈,遇到 )
就将栈顶元素出栈,最后判断栈是否为空就可以了(当然,如果遇到 )
的时候,栈就为空了,自然就可以 return false
了)。
这道题难度提升了,但解决方法依然可以用栈,只不过不是压字符串元素入栈,而是 元素下标 入栈。思路如下:
- 将
-1
入栈(后面解释为什么)。 - 遍历字符串元素时,遇到
(
就将其下标入栈,然后继续遍历; - 如果遇到
)
就将栈顶元素pop
掉,这时候判断栈是否为空,①如果不为空则更新要返回的长度值,找 原来的长度 和 用当前元素的下标减去栈顶元素的下标 的最大值【这就是为什么要实现压入-1
的原因了:用下标来求长度的话,会发现差值始终为1
】(那么可以推测出)②栈为空的话,就将当前元素的下标入栈,理由就跟一开始将-1
入栈一样。 - 结束遍历的时候返回长度值即可。
三、AC 代码
解法一:时间复杂度为 O(n)
,空间复杂度为 O(n)
class Solution {
public:
int longestValidParentheses(string s) {
int maxNum = 0;
stack<int> stk;
stk.push(-1);
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') {
stk.push(i);
} else {
stk.pop();
if (stk.empty()) {
stk.push(i);
} else {
maxNum = max(maxNum, i - stk.top());
}
}
}
return maxNum;
}
};