1.栈
刚开始压入-1,当遇到(的时候压入对应的下标,遇到)的时候pop一个栈的元素,当前下标减去栈顶元素就是以当前)结尾的子串的最长匹配长度。
正确性:栈中存的是第一个能够匹配的子串的起始下标-1。如果当前的串一直能够匹配比如()(),或者((())),那么栈始终不可能为空。但是如果)的数量大于了(,比如())(),那么就要把当前不匹配的)的下标压入栈,它就成为了新的匹配子串的前一个下标。
#include<vector>
class Solution {
public:
int longestValidParentheses(string s) {
int ans(0);
vector<int> v;
v.push_back(-1);
for(int i=0;i<s.size();++i){
if(s[i]=='(') v.push_back(i);
else{
v.pop_back();
if(v.size()==0) v.push_back(i);
else ans = max(ans,i-*(v.end()-1));
}
}
return ans;
}
};
2.普通的方法
从左往右遍历,记录( 和 )的数量为L,R。如果L==R,就找到了一个匹配的子串,如果L<R,说明当前串不匹配,L和R清0。也可以用一个变量标记L-R。
还要从右往左再遍历一遍,因为有些匹配对是从左往右开始匹配的,有些是从右往左开始的。
从右往左:(()
从左往右:)()())
class Solution {
public:
int longestValidParentheses(string s) {
int st=0,a=0,ans=0;
for(int i=0;i<s.size();++i){
if(s[i]=='(') ++a;
else --a;
if(a==0) ans = max(ans,i-st+1);
else if(a<0) a=0,st=i+1;
}
reverse(s.begin(),s.end());
st=0,a=0;
for(int i=0;i<s.size();++i){
if(s[i]==')') ++a;
else --a;
if(a==0) ans = max(ans,i-st+1);
else if(a<0) a=0,st=i+1;
}
return ans;
}
};