leetcode #32 in cpp
2016-05-25 02:46
357 查看
Given a string containing just the characters
find the length of the longest valid (well-formed) parentheses substring.
For
which has length = 2.
Another example 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:
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];
}
'('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];
}
相关文章推荐
- leetcode 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- C++中const用法总结
- CPP 虚函数、虚函数表及虚拟继承(转)
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- Deploying Control Plane Policing
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解