Given a string containing just the characters '('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
For "(()"
, the longest valid parentheses substring is "()"
, which has length = 2.
Another example is ")()())"
, where the longest valid parentheses substring is "()()"
, which has length = 4.
struct node { char c; int index; node(){} node(char _c, int _i):c(_c), index(_i){} }; class Solution { public: int longestValidParentheses(string s) { stack<node> st; st.push(node(')', -1)); int ret = 0; for(int i = 0; i < s.size(); i++) { char c = s[i]; if (c == '(') st.push(node(c, i)); else { node n = st.top(); if (n.c == '(') { st.pop(); ret = max(ret, i - st.top().index); } else st.push(node(c, i)); } } return ret; } };
answer2
动态规划:
f[i]表示i~n最长匹配括号个数,则i~n的形式如()()()
则f[i-1]的个数取决于两种情况:
1、形如 ( ()()() )中间括号的个数为f[i],则最后一个)match位置为i+f[i]+1,f[i-1]=f[i]+2
2、形如( )(()()())则I+f[i]+1的位置为粗体所示,但是可以看到f[i-1]个数应该包含后面的(()()())部分,所以f[i-1]还应该加上f[match+1]的值
class Solution { public: int longestValidParentheses(string s) { vector<int> f(s.size(),0); int ret=0; for(int i=s.size()-2;i>=0;--i){ int match=i+f[i+1]+1; //case "(((...)))" if(s[i]=='('&&match<s.size()&&s[match]==')'){ f[i]=f[i+1]+2; if(match+1<s.size()) f[i]+=f[match+1]; } ret=max(ret,f[i]); } return ret; } };
两遍扫描:
因为括号只有左括号和右括号两种,对于任意匹配括号()()()(),左括号数目一定等于右括号的数目,所以我们可以设一变量depth,当遇到左括号时++,右括号时--,若为0,则将最大值更新,若是depth<0,说明右括号多了,则将计数起点从下个位置重新开始
但是从前向后扫描只能解决任意位置都是右括号大于或等于左括号个数的问题,但对于形如(()的情况没有考虑到,所以再从后向前扫描一遍
class Solution { public: int longestValidParentheses(string s) { int answer=0; for(int i=0,start=-1,depth=0;i<s.size();i++){ if(s[i]=='(')++depth; else { --depth; if(depth<0){ start=i; depth=0; }else if(depth==0){ answer=max(answer,i-start); } } } for(int i=s.size()-1,end=s.size(),depth=0;i>=0;--i){ if(s[i]==')')++depth; else { --depth; if(depth<0){ end=i; depth=0; }else if(depth==0){ answer=max(answer,end-i); } } } return answer; } };