32. Longest Valid Parentheses
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.
Thoughts:
Use stack to keep track of "non parenthesis" index. After the scan, calculate the largest number of parenthesis characters by calculating gaps between tracked indices.
DP: I construct a array longest[] , for any longest[i], it stores the longest length of valid parentheses which is end at i.If s[i] is '(', set longest[i] to 0,because any string end with '(' cannot be a valid one.Else if s[i] is ')'If s[i-1] is '(', longest[i] = longest[i-2] + 2 Else if s[i-1] is ')'and s[i-longest[i-1]-1] == '(', longest[i] = longest[i-1] + 2 + longest[i-longest[i-1]-2]. For example, input "()(())", at i = 5, longest array is [0,2,0,0,2,0], longest[5] = longest[4] + 2 + longest[1] = 6.jerryrcwong's post
Code
class Solution {
public:
int longestValidParentheses(string s) {
int len = s.length(), answer = 0;
if(len == 0) return answer;
stack<int> st;
for(int i =0 ; i < len; i++){
if(s[i] == '(') st.push(i);
else if(!st.empty() && s[st.top()]=='(') {
st.pop();
}
else st.push(i);
}
if(st.empty()) return len;
// find longest index gaps in st
int end = len, start = 0; // here end = len is because we need to
// manually figure out the first case : end - start - 1 = # of complete parentheses characters in between two neighboring indices,
// so to be consistent initial position end here is one postition 1 over the last element in the element as if there is an "virtual"
// ')' in the end.
while(!st.empty()){
start = st.top(); st.pop();
answer = max(answer, end - start - 1);
end = start;
}
answer = max(answer, end); // compare the number of parenthesis character skiped till the first index, do not need extra "-1" since
// there is no start index any more (or the "virtual" starting index is at -1)
cout<<end<<endl;
return answer;
}
};
Code: DP
int longestValidParentheses(string s) {
if(s.length() <= 1) return 0;
int curMax = 0;
vector<int> longest(s.size(),0);
for(int i=1; i < s.length(); i++){
if(s[i] == ')'){
if(s[i-1] == '('){
longest[i] = (i-2) >= 0 ? (longest[i-2] + 2) : 2;
curMax = max(longest[i],curMax);
}
else{ // if s[i-1] == ')', combine the previous length.
if(i-longest[i-1]-1 >= 0 && s[i-longest[i-1]-1] == '('){
longest[i] = longest[i-1] + 2 + ((i-longest[i-1]-2 >= 0)?longest[i-longest[i-1]-2]:0);
curMax = max(longest[i],curMax);
}
}
}
//else if s[i] == '(', skip it, because longest[i] must be 0
}
return curMax;
}
Python
class Solution(object):
def longestValidParentheses(self, s):
"""
:type s: str
:rtype: int
"""
if len(s) < 1: return 0
res, dp = 0, [0] * len(s)
for i in range(1, len(s)):
if s[i] == ')':
if s[i- 1] == '(':
dp[i] = dp[i - 2] + 2 if i >= 2 else 2
res= max(res, dp[i])
elif s[i - 1] == ')' and i - 1 - dp[i - 1] >= 0 and s[i - 1 - dp[i - 1]] == '(':
dp[i] = dp[i-1] + 2 + (dp[i-2-dp[i-1]] if i-2-dp[i-1] >= 0 else 0)
res = max(res, dp[i])
return res
Special thanks: LeetCode Discussion Forum for the reference!
Last updated
Was this helpful?