换换口味做一下leetcode的题
最最普通的版本,时间和内存消耗都相对比较大。从头到尾扫描vector,合并相邻或中间隔着成对括号的左和右,当vector长度不变时计算所有标记成对的节点的数目,即最长子串。
class Solution {
public:
struct Node{
int state=0;//0为成对,-1为左,1为右
int num=0;
};
int longestValidParentheses(string s) {
vector<Node> v;
int maxlen=0,currlen=0;
if(strlen(s.c_str())==0)return 0;
for(int i=0;i<strlen(s.c_str());i++){
int flag=1;
if(s[i]=='(') flag=-1;
if(v.empty() || v.back().state!=flag){
Node node;
node.state=flag;
node.num=1;
v.push_back(node);
}else v.back().num++;
}
int oldsize=-1;
while(v.size()!=oldsize){
oldsize=v.size();
//合并
for(int i=0;i<v.size()-1;/*i++*/){
if(v[i].state==-1 && v[i+1].state==1){
int minnum=min(v[i].num,v[i+1].num);
v[i].num-=minnum;
v[i+1].num-=minnum;
Node temp;
temp.state=0;
temp.num=2*minnum;
v.insert(v.begin()+1+i,temp);
//it++;
}else if(i<v.size()-2 && v[i].state==-1 && v[i+1].state==0 && v[i+2].state==1){
int minnum=min(v[i].num,v[i+2].num);
v[i].num-=minnum;
v[i+2].num-=minnum;
v[i+1].num+=2*minnum;
i++;
}else i++;
}
//合并成对 删除0
for(vector<Node>::iterator it=v.begin();it!=v.end();){
if(it->num==0){
it=v.erase(it);
}else it++;
}
for(int i=0;i<v.size()-1;i++){
if(v[i].state==v[i+1].state){
v[i].num+=v[i+1].num;
v.erase(v.begin()+i+1);
}
}
}
for(vector<Node>::iterator it=v.begin();it!=v.end();it++){
if(it->state==0 && it->num > maxlen){
maxlen=it->num;
}
}
return maxlen;
}
};
还有一个计数的版本,时间消耗还是比较大,可能是因为string的reverse(吧),用lastend来记录上一个闭合括号的结束位置,判断两个闭合括号是否相连。右闭合的判定比较复杂,此处不做处理,reverse之后再互换,相当于对原串从右到左再扫一遍。因为是对称的,最后取最大值。
class Solution {
public:
int cnt(string s){
int maxlen=0,currlen=0,lastend=0;
int left=0,right=0;
bool state=false;
for(int i=0;i<strlen(s.c_str());i++){
if(s[i]=='(')state=true;//左括号是表达式开始
if(!state)continue;
if(s[i]=='(') left++;
else right++;
if(right==left){
if(i-2*left==lastend)currlen+=left*2;
else currlen=left*2;
lastend=i;
left=right=0;
state=false;
}
maxlen=max(maxlen,currlen);
}
return maxlen;
};
int longestValidParentheses(string s) {
int maxlen1=0,maxlen2=0;
maxlen1=cnt(s);
reverse(s.begin(),s.end());
for(int i=0;i<strlen(s.c_str());i++){
if(s[i]=='(')s[i]=')';
else s[i]='(';
}
maxlen2=cnt(s);
return max(maxlen1,maxlen2);
}
};
还可以用栈做,就先不写惹