题目:32. 最长有效括号链接
思路:
方法一:栈
看到括号匹配问题首先想到栈,这题求连续匹配的括号长度,因此我们首先想到如何指定弹栈,入栈的规则。
首先 需要明确栈中存的是下标,并不是元素值
s.push(-1);
-1为了 后面计算maxLen方便进行的, 不用担心越界问题,因为-1下标,并不会直接使用。
入栈规则 :代表着等待弹出
if(str[i]=='(')
{
s.push(i);
}
出栈规则:这代表着经过出栈后,
1.原栈中若是空,则代表着不用更新元素maxLen值,直接将i入栈,入栈后,栈不为空
2.栈中不为空,那么也就是说,刚才直接弹出栈的是str[i]=’(’,,又找到一队匹配括号,然后我们可以更新maxLen的值。
if (str[i]==')')
{
s.pop();
....
}
方法二:正向遍历,逆向遍历
遍历两次,空间复杂度是o(1) 存在两个变量 一个记录左括号个数,一个记录右括号个数
1.正向遍历时
保证左括号个数大于等于右括号个数 相等时更新maxLen
2.逆向遍历 保证左括号个数小于等于右括号个数 相等时更新maxLen
方法三:动态规划
代码:
方法一
class Solution {
public:
int longestValidParentheses(string str)
{
stack<int> s;
s.push(-1);
int maxLen=0;
for(int i=0;i<str.size();i++)
{
if(str[i]=='(')
{
s.push(i);
}
else if (str[i]==')')
{
s.pop();
if(s.empty())
{
s.push(i);
}else
{
maxLen=max(maxLen,i-s.top());
}
}
}
return maxLen;
}
};
方法二
class Solution {
public:
int longestValidParentheses(string str)
{
//双指针 双向遍历(也就是遍历两次)
int leftCount=0;
int rightCount=0;
int maxLen=0;
for(int i=0;i<str.size();i++)
{
if(str[i]=='(')
{
leftCount++;
}
else if(str[i]==')')
{
rightCount++;
if(rightCount==leftCount)
{
maxLen=max(maxLen,rightCount*2);
}
else if(rightCount>leftCount)//已经不连续了
{
leftCount=0;
rightCount=0;
}
}
}
//下面就是逆向遍历了。改改
leftCount=0;
rightCount=0;
for(int i=str.size()-1;i>=0;i--)//逆向
{
if(str[i]==')')//这个逆向保证右括号大于等于左括号
{
leftCount++;
}
else if(str[i]=='(')
{
rightCount++;
if(rightCount==leftCount)
{
maxLen=max(maxLen,rightCount*2);
}
else if(rightCount>leftCount)//已经不连续了
{
leftCount=0;
rightCount=0;
}
}
}
return maxLen;
}
};