您的位置:首页 > 编程语言 > C语言/C++

leetcode #32 in cpp

2016-05-25 02:46 357 查看
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.

Solution 1: USE STACK.
The key point is to realize that if there are multiple valid parentheses, between the valid parentheses must there be some '(' or ')' that are not matched. For example, "()()() (()()()()",
there are two valid parentheses separated by an un-matched '('. "((())) )) ()" there are two unmatched parentheses ')'.  So we have to find those un-matchedparentheses. Once we find those un-matched parentheses we would
know the valid parentheses and count the maximum length. For example, "()()()"-->matched[] =[1,1,1,1,1,1] so maximum length is 6. "((())) )) ()"--->matched = [1,1,1,1,1,1,0,0,1,1] and maximum length is 6. 

How to find the un-matched parentheses? Use stack. Recall that in question 20 we know how to determine a valid parentheses by stack. In this question we also use stack.We scan through
the string, every time we meet a '(', we push its index into the stack. If we meet ')', determine if the stack is empty. If so then this ')' is not matched. If thestack is not empty, then this '(' is matched by a '('. Since
we have put the '(' index in the stack, we pop the stack and know where this '(' is and mark matched[stack.top()] = 1and matched[location of ')'] = 1.

Once we are done with scanning through the string. We count the longest consecutive 1s in the matched array. In this way we determine the longest maximum length. 

 

Code: 

class Solution {
public:
int longestValidParentheses(string s) {
if(s.empty() || s.size() == 1 ) return 0;
int long_len = 0;

int len = s.length();
int matched[len] = {0};
stack<int> stk;

for(int i = 0; i < len; i++){
char c = s[i];
if(c=='('){
stk.push(i);//push the index of '('
}else{
if(!stk.empty()){//if not empty then ')' is matched by a '('
matched[i] = 1;//mark this ')' is matched
matched[stk.top()] = 1;//mark the '(' is matched
stk.pop();//remove the matched '('
}
}
}
<span style="white-space:pre">	</span>//count length of consecutive 1s
int temp_len = 0;
for(int i = 0; i < len; i ++){
if(matched[i] == 1){
temp_len ++;
}else{
temp_len = 0;
}
long_len = long_len > temp_len?long_len:temp_len;

}
return long_len;
}
};


Solution 2: USE DP

we use 1-dimension DP array to solve this problem,where dp[i] = the length of the longest valid parentheses starting from s[i].

if s[i] == ')': no valid parentheses starts from ')'. Thus dp[i] = 0;

if s[i] == '(': it has two cases

case 1: if s[i+1] == ')' then s[i] matches s[i-1]. Example is s[i......] = ['(', ')',.......]

So dp[i] = 2 + dp[i+2], where +dp[i+2] is to concatenate the valid parentheses after s[i+1] if there are any. 

case 2: if s[i+1] == '(' then the only way s[i] could match is there is a ')' right after the valid parentheses starting from s[i+1]. We know that the valid parentheses starting 

from s[i+1] has length dp[i+1]. Example is s[i,i+1,....,i+dp[i+1], i+dp[i+1] + 1 ,...] = "( (.....) )"

So 

     if(s[i+1+dp[i+1] ] == ')': dp[i] = 2 + dp[i+1] + dp[i+1+dp[i+1]+1]. 

Why are we adding dp[i+1+dp[i+1]+1]? This is because if s[i+1+dp[i+1]] is ')',  dp[i+1] would only counts for length of valid parentheses from i + 1 to i+dp[i+1]+1
since those parentheses are wrapped by s[i] and s[i+1+dp[i+1]]. Example is "( ()()() ) ()()" where dp[1] = 6 for "()()()" and it does not add "()()" into itself. Thus we
have to also add dp[i+1+dp[i+1] + 1].

In the implementation case 2 actuall covers case 1. So case 1 could be skipped. 

Code: 

if(s.empty() || s.size() == 1 ) return 0;
int long_len = 0;
int len = s.length();
int dp[len] = {0};
for(int i = len - 2; i >=0 ; i --){
if(s[i] == ')') dp[i] = 0;
else{
if(s[i+1] == ')'){//case 1. case 1 could be skipped
dp[i] = 2 ;
if(i+2<len){
dp[i] += dp[i+2];
}
}else{//case 2
if(i+1 + dp[i+1] < len && s[i+1 + dp[i+1]] == ')'){
dp[i] = 2 + dp[i+1];
if(i+1+dp[i+1] +1 < len)
dp[i]+=dp[i+2+dp[i+1]];
}
}
}
long_len = long_len > dp[i]?long_len:dp[i];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cpp leetcode