题目描述
难度:困难
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
思路一——栈
最开始未考虑嵌套括号 “(())” 这种情况,还想着怎么是困难题。后来 “()(()” 被这种中间断开也给制裁了。
查看官方题解,初始化一个用于存放字符下标的栈,并置入-1作初值。
遍历字符串,若字符是 '(' 时,直接入栈;若字符是 ')' ,先将栈中元素移出,然后判空,若栈空,放入当前索引记录,防止对空栈操作;若栈不为空,通过当前索引 - 栈顶元素的索引,能够得到当前有效括号区间的长度。
- 时间复杂度:O(n)
- 空间复杂度:O(n)
int longestValidParentheses(string s) {
int maxLength = 0, length = 0;
stack<int> index;
index.push(-1);
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(')
index.push(i);
else
{
index.pop();
if(index.empty())
index.push(i);
else
maxLength = max(maxLength,i-index.top());
}
}
return maxLength;
}
思路二——暴力
有效的括号区间一定是偶数个,因此遍历字符串,挨个字符当作起始点,2个、4个、6个……逐区间使用栈来判断是否符合规则。这种暴力想法,我也没想到,不过时间复杂度 O(n^3) 过高,会超时。
例子:
"((())"从索引0开始
2个:(( --> 无效
4个:((()--> 无效
从索引1开始
2个:(( --> 无效4个:(())--> 有效
从索引2开始
2个:() --> 有效从索引3开始
)) --> 无效综上
最长长度为 4
class Solution {
public:
bool isValid(string str)
{
stack<char> myStack;
for(int i=0;i<str.length();i++)
{
if(str[i]=='(')
myStack.push(str[i]);
else if(!myStack.empty() && myStack.top() == '(')
myStack.pop();
else
return false;
}
return myStack.empty();
}
int longestValidParentheses(string s) {
int maxLength=0;
for(int i=0;i<s.length();i++)
for (int j = 2; i + j <= s.length(); j += 2)
if (isValid(s.substr(i, j)))
maxLength = max(maxLength, j);
return maxLength;
}
};